diff options
author | Daniel Shahaf <d.s@daniel.shahaf.name> | 2020-05-26 22:06:39 +0000 |
---|---|---|
committer | Daniel Shahaf <d.s@daniel.shahaf.name> | 2020-05-28 19:40:40 +0000 |
commit | fb1aa3fe1e78ee1f521b64db062addf74ea9d263 (patch) | |
tree | 8a4a198511dad6099320b66ebb6a3139c3da48da /Src | |
parent | 40723b3991557d0f5db66cbde9feb5cbc33bce78 (diff) | |
download | zsh-fb1aa3fe1e78ee1f521b64db062addf74ea9d263.tar.gz zsh-fb1aa3fe1e78ee1f521b64db062addf74ea9d263.tar.xz zsh-fb1aa3fe1e78ee1f521b64db062addf74ea9d263.zip |
45923 (with memory leak fixed, cf. 45924): zprof: Don't tally all anonymous functions as though they were a single function named "(anon)".
Before: % zmodload zsh/zprof % () : % () : % zprof num calls time self name ----------------------------------------------------------------------------------- 1) 2 0.08 0.04 100.00% 0.08 0.04 100.00% (anon) After: % zmodload zsh/zprof % () : % () : % zprof num calls time self name ----------------------------------------------------------------------------------- 1) 1 0.04 0.04 50.45% 0.04 0.04 50.45% (anon) [:3] 2) 1 0.04 0.04 49.55% 0.04 0.04 49.55% (anon) [:2]
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/zprof.c | 31 | ||||
-rw-r--r-- | Src/exec.c | 20 |
2 files changed, 46 insertions, 5 deletions
diff --git a/Src/Modules/zprof.c b/Src/Modules/zprof.c index bc97771c0..56cdab888 100644 --- a/Src/Modules/zprof.c +++ b/Src/Modules/zprof.c @@ -213,7 +213,25 @@ bin_zprof(UNUSED(char *nam), UNUSED(char **args), Options ops, UNUSED(int func)) return 0; } -/**/ +static char * +name_for_anonymous_function(char *name) +{ + char lineno[DIGBUFSIZE]; + char *parts[7]; + + convbase(lineno, funcstack[0].flineno, 10); + + parts[0] = name; + parts[1] = " ["; + parts[2] = funcstack[0].filename ? funcstack[0].filename : ""; + parts[3] = ":"; + parts[4] = lineno; + parts[5] = "]"; + parts[6] = NULL; + + return sepjoin(parts, "", 1); +} + static int zprof_wrapper(Eprog prog, FuncWrap w, char *name) { @@ -224,12 +242,19 @@ zprof_wrapper(Eprog prog, FuncWrap w, char *name) struct timeval tv; struct timezone dummy; double prev = 0, now; + char *name_for_lookups; + + if (is_anonymous_function_name(name)) { + name_for_lookups = name_for_anonymous_function(name); + } else { + name_for_lookups = name; + } if (zprof_module && !(zprof_module->node.flags & MOD_UNLOAD)) { active = 1; - if (!(f = findpfunc(name))) { + if (!(f = findpfunc(name_for_lookups))) { f = (Pfunc) zalloc(sizeof(*f)); - f->name = ztrdup(name); + f->name = ztrdup(name_for_lookups); f->calls = 0; f->time = f->self = 0.0; f->next = calls; diff --git a/Src/exec.c b/Src/exec.c index 2b8e2167f..29f4fc5ca 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5147,10 +5147,26 @@ exectime(Estate state, UNUSED(int do_exec)) return lastval; } -/* Define a shell function */ - +/* The string displayed in lieu of the name of an anonymous function (in PS4, + * zprof output, etc) + */ static const char *const ANONYMOUS_FUNCTION_NAME = "(anon)"; +/* + * Take a function name argument and return true iff it is equal to the string + * used for the names of anonymous functions, "(anon)". + * + * Note that it's possible to define a named function literally called "(anon)" + * (though I doubt anyone would ever do that). + */ +/**/ +int is_anonymous_function_name(const char *name) +{ + return !strcmp(name, ANONYMOUS_FUNCTION_NAME); +} + +/* Define a shell function */ + /**/ static int execfuncdef(Estate state, Eprog redir_prog) |