- added ability to filter VM disassembly dump

Use '-dumpdisasm something' to output functions with 'something' in their printable names
Open and close output file only once when processing code generated by Dehacked, and calculate its sizes as well
This commit is contained in:
alexey.lysiuk 2020-01-19 16:48:35 +02:00
parent 09016b7c05
commit 5a19010699
3 changed files with 79 additions and 32 deletions

View file

@ -739,7 +739,7 @@ static void (*MBFCodePointerFactories[])(FunctionCallEmitter&, int, int) =
// Creates new functions for the given state so as to convert MBF-args (misc1 and misc2) into real args.
void SetDehParams(FState *state, int codepointer)
static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &disasmdump)
{
static const uint8_t regts[] = { REGT_POINTER, REGT_POINTER, REGT_POINTER };
int value1 = state->GetMisc1();
@ -795,15 +795,8 @@ void SetDehParams(FState *state, int codepointer)
state->SetAction(sfunc);
sfunc->PrintableName.Format("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2);
if (Args->CheckParm("-dumpdisasm"))
{
FILE *dump = fopen("disasm.txt", "a");
if (dump != nullptr)
{
DumpFunction(dump, sfunc, sfunc->PrintableName.GetChars(), (int)sfunc->PrintableName.Len());
}
fclose(dump);
}
disasmdump.Write(sfunc, sfunc->PrintableName);
#ifdef HAVE_VM_JIT
if (Args->CheckParm("-dumpjit"))
{
@ -2651,10 +2644,12 @@ static void UnloadDehSupp ()
{
if (--DehUseCount <= 0)
{
VMDisassemblyDumper disasmdump(VMDisassemblyDumper::Append);
// Handle MBF params here, before the required arrays are cleared
for (unsigned int i=0; i < MBFParamStates.Size(); i++)
{
SetDehParams(MBFParamStates[i].state, MBFParamStates[i].pointer);
SetDehParams(MBFParamStates[i].state, MBFParamStates[i].pointer, disasmdump);
}
MBFParamStates.Clear();
MBFParamStates.ShrinkToFit();

View file

@ -809,11 +809,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo
void FFunctionBuildList::Build()
{
int codesize = 0;
int datasize = 0;
FILE *dump = nullptr;
if (Args->CheckParm("-dumpdisasm")) dump = fopen("disasm.txt", "w");
VMDisassemblyDumper disasmdump(VMDisassemblyDumper::Overwrite);
for (auto &item : mItems)
{
@ -900,13 +896,8 @@ void FFunctionBuildList::Build()
}
}
if (dump != nullptr)
{
DumpFunction(dump, sfunc, item.PrintableName.GetChars(), (int)item.PrintableName.Len());
codesize += sfunc->CodeSize;
datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) +
sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString);
}
disasmdump.Write(sfunc, item.PrintableName);
sfunc->Unsafe = ctx.Unsafe;
}
catch (CRecoverableError &err)
@ -916,15 +907,7 @@ void FFunctionBuildList::Build()
}
}
delete item.Code;
if (dump != nullptr)
{
fflush(dump);
}
}
if (dump != nullptr)
{
fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes", codesize * 4, datasize);
fclose(dump);
disasmdump.Flush();
}
VMFunction::CreateRegUseInfo();
FScriptPosition::StrictErrors = false;
@ -1122,3 +1105,50 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray<ExpEmit>
return retreg;
}
VMDisassemblyDumper::VMDisassemblyDumper(const FileOperationType operation)
{
static const char *const DUMP_ARG_NAME = "-dumpdisasm";
if (Args->CheckParm(DUMP_ARG_NAME))
{
dump = fopen("disasm.txt", operation == Overwrite ? "w" : "a");
namefilter = Args->CheckValue(DUMP_ARG_NAME);
namefilter.ToLower();
}
}
VMDisassemblyDumper::~VMDisassemblyDumper()
{
if (dump != nullptr)
{
fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes\n", codesize * 4, datasize);
fclose(dump);
}
}
void VMDisassemblyDumper::Write(VMScriptFunction *sfunc, const FString &fname)
{
if (dump != nullptr)
{
if (namefilter.Len() > 0 && fname.MakeLower().IndexOf(namefilter) == -1)
{
return;
}
assert(sfunc != nullptr);
DumpFunction(dump, sfunc, fname, (int)fname.Len());
codesize += sfunc->CodeSize;
datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) +
sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString);
}
}
void VMDisassemblyDumper::Flush()
{
if (dump != nullptr)
{
fflush(dump);
}
}

View file

@ -211,4 +211,26 @@ public:
}
};
class VMDisassemblyDumper
{
public:
enum FileOperationType
{
Overwrite,
Append
};
explicit VMDisassemblyDumper(const FileOperationType operation);
~VMDisassemblyDumper();
void Write(VMScriptFunction *sfunc, const FString &fname);
void Flush();
private:
FILE *dump = nullptr;
FString namefilter;
int codesize = 0;
int datasize = 0;
};
#endif