diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 9688d3cab..5aef53c81 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -66,6 +66,8 @@ #include "types.h" #include "m_argv.h" +void JitDumpLog(FILE *file, VMScriptFunction *func); + // [SO] Just the way Randy said to do it :) // [RH] Made this CVAR_SERVERINFO CVAR (Int, infighting, 0, CVAR_SERVERINFO) @@ -824,6 +826,15 @@ void SetDehParams(FState *state, int codepointer) } fclose(dump); } + if (Args->CheckParm("-dumpjit")) + { + FILE *dump = fopen("dumpjit.txt", "a"); + if (dump != nullptr) + { + JitDumpLog(dump, sfunc); + } + fclose(dump); + } } } diff --git a/src/scripting/backend/vmbuilder.cpp b/src/scripting/backend/vmbuilder.cpp index a144a30cc..89061d128 100644 --- a/src/scripting/backend/vmbuilder.cpp +++ b/src/scripting/backend/vmbuilder.cpp @@ -35,6 +35,7 @@ #include "vmbuilder.h" #include "codegen.h" #include "m_argv.h" +#include "scripting/vm/jit.h" struct VMRemap { @@ -939,7 +940,22 @@ void FFunctionBuildList::Build() fclose(dump); } FScriptPosition::StrictErrors = false; + if (Args->CheckParm("-dumpjit")) DumpJit(); mItems.Clear(); mItems.ShrinkToFit(); FxAlloc.FreeAllBlocks(); -} \ No newline at end of file +} + +void FFunctionBuildList::DumpJit() +{ + FILE *dump = fopen("dumpjit.txt", "w"); + if (dump == nullptr) + return; + + for (auto &item : mItems) + { + JitDumpLog(dump, item.Function); + } + + fclose(dump); +} diff --git a/src/scripting/backend/vmbuilder.h b/src/scripting/backend/vmbuilder.h index d33688276..cbac7a239 100644 --- a/src/scripting/backend/vmbuilder.h +++ b/src/scripting/backend/vmbuilder.h @@ -146,6 +146,8 @@ class FFunctionBuildList TArray mItems; + void DumpJit(); + public: VMFunction *AddFunction(PNamespace *curglobals, const VersionInfo &ver, PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate, int statecnt, int lumpnum); void Build(); diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 7f68f88d8..fcf353cee 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -91,6 +91,38 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) } } +void JitDumpLog(FILE *file, VMScriptFunction *sfunc) +{ + using namespace asmjit; + StringLogger logger; + try + { + auto *jit = JitGetRuntime(); + + ThrowingErrorHandler errorHandler; + CodeHolder code; + code.init(jit->getCodeInfo()); + code.setErrorHandler(&errorHandler); + code.setLogger(&logger); + + JitCompiler compiler(&code, sfunc); + compiler.Codegen(); + + fwrite(logger.getString(), logger.getLength(), 1, file); + } + catch (const std::exception &e) + { + fwrite(logger.getString(), logger.getLength(), 1, file); + + FString err; + err.Format("Unexpected JIT error: %s\n", e.what()); + fwrite(err.GetChars(), err.Len(), 1, file); + fclose(file); + + I_FatalError("Unexpected JIT error: %s\n", e.what()); + } +} + ///////////////////////////////////////////////////////////////////////////// static const char *OpNames[NUM_OPS] = @@ -111,14 +143,13 @@ void JitCompiler::Codegen() int i = (int)(ptrdiff_t)(pc - sfunc->Code); op = pc->op; - cc.bind(labels[i]); - - ResetTemp(); - FString lineinfo; - lineinfo.Format("; %s(line %d): %02x%02x%02x%02x %s", sfunc->PrintableName.GetChars(), sfunc->PCToLine(pc), pc->op, pc->a, pc->b, pc->c, OpNames[op]); + lineinfo.Format("; line %d: %02x%02x%02x%02x %s", sfunc->PCToLine(pc), pc->op, pc->a, pc->b, pc->c, OpNames[op]); + cc.comment("", 0); cc.comment(lineinfo.GetChars(), lineinfo.Len()); + cc.bind(labels[i]); + ResetTemp(); EmitOpcode(); pc++; @@ -148,10 +179,17 @@ void JitCompiler::Setup() ResetTemp(); + static const char *marks = "======================================================="; + cc.comment("", 0); + cc.comment(marks, 56); + FString funcname; funcname.Format("Function: %s", sfunc->PrintableName.GetChars()); cc.comment(funcname.GetChars(), funcname.Len()); + cc.comment(marks, 56); + cc.comment("", 0); + auto unusedFunc = cc.newIntPtr("func"); // VMFunction* args = cc.newIntPtr("args"); // VMValue *params numargs = cc.newInt32("numargs"); // int numargs @@ -207,6 +245,11 @@ void JitCompiler::Setup() regA[i] = cc.newIntPtr(regname.GetChars()); } + int size = sfunc->CodeSize; + labels.Resize(size); + for (int i = 0; i < size; i++) + labels[i] = cc.newLabel(); + frameD = cc.newIntPtr(); frameF = cc.newIntPtr(); frameS = cc.newIntPtr(); @@ -369,10 +412,6 @@ void JitCompiler::Setup() for (int i = 0; i < sfunc->NumRegA; i++) cc.mov(regA[i], x86::ptr(frameA, i * sizeof(void*))); } - - int size = sfunc->CodeSize; - labels.Resize(size); - for (int i = 0; i < size; i++) labels[i] = cc.newLabel(); } void JitCompiler::EmitPopFrame() diff --git a/src/scripting/vm/jit.h b/src/scripting/vm/jit.h index 923e02df3..8188aa9b0 100644 --- a/src/scripting/vm/jit.h +++ b/src/scripting/vm/jit.h @@ -5,3 +5,4 @@ JitFuncPtr JitCompile(VMScriptFunction *func); void JitCleanUp(VMScriptFunction *func); +void JitDumpLog(FILE *file, VMScriptFunction *func);