diff options
Diffstat (limited to 'compiler/vmprofiler.nim')
-rw-r--r-- | compiler/vmprofiler.nim | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/compiler/vmprofiler.nim b/compiler/vmprofiler.nim new file mode 100644 index 000000000..3f0db84bd --- /dev/null +++ b/compiler/vmprofiler.nim @@ -0,0 +1,45 @@ + +import options, vmdef, lineinfos, msgs + +import std/[times, strutils, tables] + +proc enter*(prof: var Profiler, c: PCtx, tos: PStackFrame) {.inline.} = + if optProfileVM in c.config.globalOptions: + prof.tEnter = cpuTime() + prof.tos = tos + +proc leaveImpl(prof: var Profiler, c: PCtx) {.noinline.} = + let tLeave = cpuTime() + var tos = prof.tos + var data = c.config.vmProfileData.data + while tos != nil: + if tos.prc != nil: + let li = tos.prc.info + if li notin data: + data[li] = ProfileInfo() + data[li].time += tLeave - prof.tEnter + if tos == prof.tos: + inc data[li].count + tos = tos.next + +proc leave*(prof: var Profiler, c: PCtx) {.inline.} = + if optProfileVM in c.config.globalOptions: + leaveImpl(prof, c) + +proc dump*(conf: ConfigRef, pd: ProfileData): string = + var data = pd.data + result = "\nprof: µs #instr location" + for i in 0..<32: + var tMax: float + var infoMax: ProfileInfo = default(ProfileInfo) + var flMax: TLineInfo = default(TLineInfo) + for fl, info in data: + if info.time > infoMax.time: + infoMax = info + flMax = fl + if infoMax.count == 0: + break + result.add " " & align($int(infoMax.time * 1e6), 10) & + align($int(infoMax.count), 10) & " " & + conf.toFileLineCol(flMax) & "\n" + data.del flMax |