From 29a2e497fbab7bb36571beb551353c13f5c2c3fb Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Dec 2018 15:29:37 -0800 Subject: [PATCH 1/4] refs #10106 --- lib/pure/nimprof.nim | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 27b7d3ecacbe..d1cdeb25dadc 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -39,6 +39,15 @@ type st: StackTrace ProfileData = array[0..64*1024-1, ptr ProfileEntry] +proc `==`(x, y: cstring): bool {.noSideEffect, inline.} = + ## Checks for equality between two `cstring` variables. + # copied over from system.nim as workaround for #10106 + proc strcmp(a, b: cstring): cint {.noSideEffect, + importc, header: "".} + if pointer(x) == pointer(y): result = true + elif x.isNil or y.isNil: result = false + else: result = strcmp(x, y) == 0 + proc `==`(a, b: StackTrace): bool = for i in 0 .. high(a.lines): if a[i] != b[i]: return false @@ -146,7 +155,7 @@ else: dec gTicker proc hook(st: StackTrace) {.nimcall, locks: 0.} = - #echo "profiling! ", interval + # echo "profiling! ", interval if interval == 0: hookAux(st, 1) else: @@ -167,7 +176,7 @@ proc writeProfile() {.noconv.} = when declared(system.StackTrace): system.profilerHook = nil const filename = "profile_results.txt" - echo "writing " & filename & "..." + echo "writing " & filename & " ..." var f: File if open(f, filename, fmWrite): sort(profileData, cmpEntries) From 6ccaaf2bf58fac27be111319d9b4b6e0d4b40118 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Dec 2018 15:46:06 -0800 Subject: [PATCH 2/4] bugfix in "for i in 0.. 1: inc sum, profileData[i].total writeLine(f, "Entry: ", i+1, "/", entries, " Calls: ", From 5a8a2c19c598cc714d2dc54ae89794d2afad8e67 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Dec 2018 16:16:32 -0800 Subject: [PATCH 3/4] * remove duplicate `type StackTrace = object` definition * add line to stacktrace in profiler results --- lib/pure/nimprof.nim | 9 ++------- lib/system/profiler.nim | 10 ++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 4ccc43cae67a..162435879865 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -26,12 +26,6 @@ const withThreads = compileOption("threads") tickCountCorrection = 50_000 -when not declared(system.StackTrace): - type StackTrace = object - lines: array[0..20, cstring] - files: array[0..20, cstring] - proc `[]`*(st: StackTrace, i: int): cstring = st.lines[i] - # We use a simple hash table of bounded size to keep track of the stack traces: type ProfileEntry = object @@ -206,8 +200,9 @@ proc writeProfile() {.noconv.} = for ii in 0..high(StackTrace.lines): let procname = profileData[i].st[ii] let filename = profileData[i].st.files[ii] + let line = profileData[i].st.locLines[ii] if isNil(procname): break - writeLine(f, " ", $filename & ": " & $procname, " ", perProc[$procname] // totalCalls) + writeLine(f, " ", $filename & ":" & $line & " " & $procname, " ", perProc[$procname] // totalCalls) close(f) echo "... done" else: diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 0649f117674e..18b7bcf8f74a 100644 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -25,6 +25,13 @@ type StackTrace* = object lines*: array[0..MaxTraceLen-1, cstring] files*: array[0..MaxTraceLen-1, cstring] + #[ + TODO(minor): + * rename to loc after renaming `lines` to procnames + * make StackTrace = object: entry: array[0..MaxTraceLen-1, StackTraceEntry] + with some StackTraceEntry object + ]# + locLines*: array[0..MaxTraceLen-1, int] ProfilerHook* = proc (st: StackTrace) {.nimcall.} proc `[]`*(st: StackTrace, i: int): cstring = st.lines[i] @@ -40,6 +47,7 @@ proc captureStackTrace(f: PFrame, st: var StackTrace) = # the (-1) is for the "..." entry st.lines[i] = it.procname st.files[i] = it.filename + st.locLines[i] = it.line inc(i) inc(total) it = it.prev @@ -52,10 +60,12 @@ proc captureStackTrace(f: PFrame, st: var StackTrace) = if total != i: st.lines[i] = "..." st.files[i] = "..." + st.locLines[i] = 0 inc(i) while b != nil and i <= high(st.lines): st.lines[i] = b.procname st.files[i] = b.filename + st.locLines[i] = b.line inc(i) b = b.prev From 6b9fb6fc3ed12df0e56bb55024377c1e8378e62f Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Dec 2018 17:12:25 -0800 Subject: [PATCH 4/4] fix preexisting typo --- lib/system/profiler.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 18b7bcf8f74a..d3ef1311bda8 100644 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -11,7 +11,7 @@ # code generator. The idea is to inject the instruction stream # with 'nimProfile()' calls. These calls are injected at every loop end # (except perhaps loops that have no side-effects). At every Nth call a -# stack trace is taken. A stack tace is a list of cstrings. +# stack trace is taken. A stack trace is a list of cstrings. when defined(profiler) and defined(memProfiler): {.error: "profiler and memProfiler cannot be defined at the same time (See Embedded Stack Trace Profiler (ESTP) User Guide) for more details".} @@ -26,7 +26,7 @@ type lines*: array[0..MaxTraceLen-1, cstring] files*: array[0..MaxTraceLen-1, cstring] #[ - TODO(minor): + todo(minor): * rename to loc after renaming `lines` to procnames * make StackTrace = object: entry: array[0..MaxTraceLen-1, StackTraceEntry] with some StackTraceEntry object