diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 4523143d76..78deccae05 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -98,6 +98,8 @@ asmjit::CCFunc *JitCompiler::Codegen() { Setup(); + LatestLine = { 0, (ptrdiff_t)0, -1, {} }; + pc = sfunc->Code; auto end = pc + sfunc->CodeSize; while (pc != end) @@ -105,10 +107,21 @@ asmjit::CCFunc *JitCompiler::Codegen() int i = (int)(ptrdiff_t)(pc - sfunc->Code); op = pc->op; + int curLine = sfunc->PCToLine(pc); + auto label = cc.newLabel (); + cc.bind (label); + LatestLine.Label = label; + if (curLine != LatestLine.LineNumber) + { + LatestLine.LineNumber = curLine; + LatestLine.VMInstructionIndex = i; + LineInfo.Push (LatestLine); + } + if (op != OP_PARAM && op != OP_PARAMI && op != OP_VTBL) { FString lineinfo; - lineinfo.Format("; line %d: %02x%02x%02x%02x %s", sfunc->PCToLine(pc), pc->op, pc->a, pc->b, pc->c, OpNames[op]); + lineinfo.Format("; line %d: %02x%02x%02x%02x %s", curLine, pc->op, pc->a, pc->b, pc->c, OpNames[op]); cc.comment("", 0); cc.comment(lineinfo.GetChars(), lineinfo.Len()); } @@ -125,6 +138,21 @@ asmjit::CCFunc *JitCompiler::Codegen() cc.endFunc(); cc.finalize(); + auto code = cc.getCode (); + for (unsigned int j = 0; j < LineInfo.Size (); j++) + { + auto info = LineInfo[j]; + + if (!code->isLabelValid (info.Label)) + { + continue; + } + + info.InstructionIndex = code->getLabelOffset (info.Label); + + LineInfo[j] = info; + } + return func; } diff --git a/src/scripting/vm/jit_runtime.cpp b/src/scripting/vm/jit_runtime.cpp index 6c608b6dad..249ccfc2bd 100644 --- a/src/scripting/vm/jit_runtime.cpp +++ b/src/scripting/vm/jit_runtime.cpp @@ -15,6 +15,7 @@ struct JitFuncInfo { FString name; FString filename; + TArray LineInfo; void *start; void *end; }; @@ -301,7 +302,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler) if (result == 0) I_Error("RtlAddFunctionTable failed"); - JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, startaddr, endaddr }); + JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr }); #endif return p; @@ -957,6 +958,20 @@ public: }; #endif +int JITPCToLine(uint8_t *pc, const JitFuncInfo *info) +{ + int PCIndex = int(pc - ((uint8_t *) (info->start))); + if (info->LineInfo.Size () == 1) return info->LineInfo[0].LineNumber; + for (unsigned i = 1; i < info->LineInfo.Size (); i++) + { + if (info->LineInfo[i].InstructionIndex >= PCIndex) + { + return info->LineInfo[i - 1].LineNumber; + } + } + return -1; +} + FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc) { for (unsigned int i = 0; i < JitDebugInfo.Size(); i++) @@ -964,12 +979,7 @@ FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc) const auto &info = JitDebugInfo[i]; if (pc >= info.start && pc < info.end) { - int line = -1; - /*for (unsigned int j = 0; j < info.lines.Size(); j++) - { - if (info.lines[j].pc <= pc) - line = info.lines[j].line; - }*/ + int line = JITPCToLine ((uint8_t *)pc, &info); FString s; diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 89eb3dd63d..8600486098 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -25,6 +25,14 @@ extern int VMCalls[10]; #define ABCs (pc[0].i24) #define JMPOFS(x) ((x)->i24) +struct JitLineInfo +{ + uint16_t VMInstructionIndex; + ptrdiff_t InstructionIndex; + int32_t LineNumber; + asmjit::Label Label; +}; + class JitCompiler { public: @@ -33,6 +41,8 @@ public: asmjit::CCFunc *Codegen(); VMScriptFunction *GetScriptFunction() { return sfunc; } + TArray LineInfo; + private: // Declare EmitXX functions for the opcodes: #define xx(op, name, mode, alt, kreg, ktype) void Emit##op(); @@ -260,6 +270,8 @@ private: TArray regA; TArray regS; + JitLineInfo LatestLine; + struct OpcodeLabel { asmjit::CBNode *cursor = nullptr;