VM profiler (#14833)

* Crude VM profiler

* Added --profileVM flag, refactoring

* fixed FileLine hash

* Use TLineInfo instead of own FileLine, updated formatting

* Refactoring, moved PStackFrame to vmdefs for cleaner data structure

* Moved vmprofiler to separate file

* Simplified TLineInfo hash, use toFileLineCol for output

* Hash

* Moved profile data into Config, dump only once at end of run

* Changed profile output header to show '#instr' instead of 'count'

* Do not accumulate instrcount for non-top frames

Co-authored-by: Ico Doornekamp <git@zevv.nl>
This commit is contained in:
Ico Doornekamp 2020-07-09 19:18:35 +02:00 • committed by GitHub
commit d7ccd82eac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 15 deletions

View file

@ -16,7 +16,7 @@ import
strutils, msgs, vmdef, vmgen, nimsets, types, passes,
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl,
modulegraphs, sighashes, int128
modulegraphs, sighashes, int128, vmprofiler
from semfold import leValueConv, ordinalValToString
from evaltempl import evalTemplate
@ -27,17 +27,6 @@ const
when hasFFI:
import evalffi
type
PStackFrame* = ref TStackFrame
TStackFrame* = object
prc: PSym # current prc; proc that is evaluated
slots: seq[TFullReg] # parameters passed to the proc + locals;
# parameters come first
next: PStackFrame # for stacking
comesFrom: int
safePoints: seq[int] # used for exception handling
# XXX 'break' should perform cleanup actions
# What does the C backend do for it?
proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) =
if x != nil:
@ -552,6 +541,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
"ra", regDescr("ra", ra), "rb", regDescr("rb", instr.regB),
"rc", regDescr("rc", instr.regC)]
c.profiler.enter(c, tos)
case instr.opcode
of opcEof: return regs[ra]
of opcRet:
@ -2077,6 +2068,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
if regs[ra].node.strVal.isNil: regs[ra].node.strVal = newStringOfCap(1000)
storeAny(regs[ra].node.strVal, typ, regs[rb].regToNode, c.config)
c.profiler.leave(c)
inc pc
proc execute(c: PCtx, start: int): PNode =