diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index 79d0b7fe6..3183edcfb 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -39,6 +39,10 @@ #include "r_state.h" #include "textures/textures.h" #include "math/cmath.h" +#include "stats.h" + +extern cycle_t VMCycles[10]; +extern int VMCalls[10]; // This must be a separate function because the VC compiler would otherwise allocate memory on the stack for every separate instance of the exception object that may get thrown. void ThrowAbortException(EVMAbortException reason, const char *moreinfo, ...); diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 76a7156cb..1d685c69c 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -609,7 +609,9 @@ begin: { try { + VMCycles[0].Unclock(); numret = static_cast(call)->NativeCall(reg.param + f->NumParam - B, call->DefaultArgs, B, returns, C); + VMCycles[0].Clock(); } catch (CVMAbortException &err) { @@ -621,6 +623,7 @@ begin: } else { + VMCalls[0]++; VMScriptFunction *script = static_cast(call); VMFrame *newf = stack->AllocFrame(script); VMFillParams(reg.param + f->NumParam - B, newf, B); @@ -663,7 +666,10 @@ begin: { try { - return static_cast(call)->NativeCall(reg.param + f->NumParam - B, call->DefaultArgs, B, ret, numret); + VMCycles[0].Unclock(); + auto r = static_cast(call)->NativeCall(reg.param + f->NumParam - B, call->DefaultArgs, B, ret, numret); + VMCycles[0].Clock(); + return r; } catch (CVMAbortException &err) { @@ -675,6 +681,7 @@ begin: } else { // FIXME: Not a true tail call + VMCalls[0]++; VMScriptFunction *script = static_cast(call); VMFrame *newf = stack->AllocFrame(script); VMFillParams(reg.param + f->NumParam - B, newf, B); diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index f9f04e425..c500c9359 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -35,6 +35,10 @@ #include #include "dobject.h" #include "v_text.h" +#include "stats.h" + +cycle_t VMCycles[10]; +int VMCalls[10]; IMPLEMENT_CLASS(VMException, false, false) IMPLEMENT_CLASS(VMFunction, true, true) @@ -463,11 +467,14 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur } else { + VMCycles[0].Clock(); + VMCalls[0]++; AllocFrame(static_cast(func)); allocated = true; VMFillParams(params, TopFrame(), numparams); int numret = VMExec(this, static_cast(func)->Code, results, numresults); PopFrame(); + VMCycles[0].Unclock(); return numret; } } @@ -573,3 +580,17 @@ void ThrowVMException(VMException *x) { throw x; } + + +ADD_STAT(VM) +{ + double added = 0; + int addedc = 0; + for (auto d : VMCycles) added += d.TimeMS(); + for (auto d : VMCalls) addedc += d; + memmove(&VMCycles[1], &VMCycles[0], 9 * sizeof(cycle_t)); + memmove(&VMCalls[1], &VMCalls[0], 9 * sizeof(int)); + VMCycles[0].Reset(); + VMCalls[0] = 0; + return FStringf("VM time in last 10 tics: %f ms, %d calls", added, addedc); +} \ No newline at end of file