Add line numbers to JIT stack traces. (#667)

This commit is contained in:
Chronos Ouroboros 2018-12-18 21:45:40 -02:00 committed by Magnus Norddahl
parent 9a2b3792ef
commit bad8c18c58
3 changed files with 58 additions and 8 deletions

View file

@ -98,6 +98,8 @@ asmjit::CCFunc *JitCompiler::Codegen()
{ {
Setup(); Setup();
LatestLine = { 0, (ptrdiff_t)0, -1, {} };
pc = sfunc->Code; pc = sfunc->Code;
auto end = pc + sfunc->CodeSize; auto end = pc + sfunc->CodeSize;
while (pc != end) while (pc != end)
@ -105,10 +107,21 @@ asmjit::CCFunc *JitCompiler::Codegen()
int i = (int)(ptrdiff_t)(pc - sfunc->Code); int i = (int)(ptrdiff_t)(pc - sfunc->Code);
op = pc->op; 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) if (op != OP_PARAM && op != OP_PARAMI && op != OP_VTBL)
{ {
FString lineinfo; 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("", 0);
cc.comment(lineinfo.GetChars(), lineinfo.Len()); cc.comment(lineinfo.GetChars(), lineinfo.Len());
} }
@ -125,6 +138,21 @@ asmjit::CCFunc *JitCompiler::Codegen()
cc.endFunc(); cc.endFunc();
cc.finalize(); 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; return func;
} }

View file

@ -15,6 +15,7 @@ struct JitFuncInfo
{ {
FString name; FString name;
FString filename; FString filename;
TArray<JitLineInfo> LineInfo;
void *start; void *start;
void *end; void *end;
}; };
@ -301,7 +302,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
if (result == 0) if (result == 0)
I_Error("RtlAddFunctionTable failed"); 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 #endif
return p; return p;
@ -957,6 +958,20 @@ public:
}; };
#endif #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) FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc)
{ {
for (unsigned int i = 0; i < JitDebugInfo.Size(); i++) for (unsigned int i = 0; i < JitDebugInfo.Size(); i++)
@ -964,12 +979,7 @@ FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc)
const auto &info = JitDebugInfo[i]; const auto &info = JitDebugInfo[i];
if (pc >= info.start && pc < info.end) if (pc >= info.start && pc < info.end)
{ {
int line = -1; int line = JITPCToLine ((uint8_t *)pc, &info);
/*for (unsigned int j = 0; j < info.lines.Size(); j++)
{
if (info.lines[j].pc <= pc)
line = info.lines[j].line;
}*/
FString s; FString s;

View file

@ -25,6 +25,14 @@ extern int VMCalls[10];
#define ABCs (pc[0].i24) #define ABCs (pc[0].i24)
#define JMPOFS(x) ((x)->i24) #define JMPOFS(x) ((x)->i24)
struct JitLineInfo
{
uint16_t VMInstructionIndex;
ptrdiff_t InstructionIndex;
int32_t LineNumber;
asmjit::Label Label;
};
class JitCompiler class JitCompiler
{ {
public: public:
@ -33,6 +41,8 @@ public:
asmjit::CCFunc *Codegen(); asmjit::CCFunc *Codegen();
VMScriptFunction *GetScriptFunction() { return sfunc; } VMScriptFunction *GetScriptFunction() { return sfunc; }
TArray<JitLineInfo> LineInfo;
private: private:
// Declare EmitXX functions for the opcodes: // Declare EmitXX functions for the opcodes:
#define xx(op, name, mode, alt, kreg, ktype) void Emit##op(); #define xx(op, name, mode, alt, kreg, ktype) void Emit##op();
@ -260,6 +270,8 @@ private:
TArray<asmjit::X86Gp> regA; TArray<asmjit::X86Gp> regA;
TArray<asmjit::X86Gp> regS; TArray<asmjit::X86Gp> regS;
JitLineInfo LatestLine;
struct OpcodeLabel struct OpcodeLabel
{ {
asmjit::CBNode *cursor = nullptr; asmjit::CBNode *cursor = nullptr;