mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 8.1.1684: profiling functionality is spread out
Problem: Profiling functionality is spread out. Solution: Put profiling functionality in profiling.c. (Yegappan Lakshmanan, closes #4666)
This commit is contained in:
224
src/userfunc.c
224
src/userfunc.c
@@ -29,7 +29,6 @@
|
||||
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
|
||||
|
||||
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
|
||||
#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
|
||||
|
||||
/*
|
||||
* All user-defined functions are found in this hashtable.
|
||||
@@ -51,13 +50,6 @@ static char *e_funcdict = N_("E717: Dictionary entry already exists");
|
||||
static char *e_funcref = N_("E718: Funcref required");
|
||||
static char *e_nofunc = N_("E130: Unknown function: %s");
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
static void func_do_profile(ufunc_T *fp);
|
||||
static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self);
|
||||
static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self);
|
||||
static int prof_total_cmp(const void *s1, const void *s2);
|
||||
static int prof_self_cmp(const void *s1, const void *s2);
|
||||
#endif
|
||||
static void funccal_unref(funccall_T *fc, ufunc_T *fp, int force);
|
||||
|
||||
void
|
||||
@@ -1312,6 +1304,12 @@ restore_funccal(void)
|
||||
}
|
||||
}
|
||||
|
||||
funccall_T *
|
||||
get_current_funccal(void)
|
||||
{
|
||||
return current_funccal;
|
||||
}
|
||||
|
||||
#if defined(EXITFREE) || defined(PROTO)
|
||||
void
|
||||
free_all_functions(void)
|
||||
@@ -2762,36 +2760,6 @@ get_expanded_name(char_u *name, int check)
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_PROFILE) || defined(PROTO)
|
||||
/*
|
||||
* Start profiling function "fp".
|
||||
*/
|
||||
static void
|
||||
func_do_profile(ufunc_T *fp)
|
||||
{
|
||||
int len = fp->uf_lines.ga_len;
|
||||
|
||||
if (!fp->uf_prof_initialized)
|
||||
{
|
||||
if (len == 0)
|
||||
len = 1; /* avoid getting error for allocating zero bytes */
|
||||
fp->uf_tm_count = 0;
|
||||
profile_zero(&fp->uf_tm_self);
|
||||
profile_zero(&fp->uf_tm_total);
|
||||
if (fp->uf_tml_count == NULL)
|
||||
fp->uf_tml_count = ALLOC_CLEAR_MULT(int, len);
|
||||
if (fp->uf_tml_total == NULL)
|
||||
fp->uf_tml_total = ALLOC_CLEAR_MULT(proftime_T, len);
|
||||
if (fp->uf_tml_self == NULL)
|
||||
fp->uf_tml_self = ALLOC_CLEAR_MULT(proftime_T, len);
|
||||
fp->uf_tml_idx = -1;
|
||||
if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
|
||||
|| fp->uf_tml_self == NULL)
|
||||
return; /* out of memory */
|
||||
fp->uf_prof_initialized = TRUE;
|
||||
}
|
||||
|
||||
fp->uf_profiling = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the profiling results for all functions in file "fd".
|
||||
@@ -2871,121 +2839,6 @@ func_dump_profile(FILE *fd)
|
||||
vim_free(sorttab);
|
||||
}
|
||||
|
||||
static void
|
||||
prof_sort_list(
|
||||
FILE *fd,
|
||||
ufunc_T **sorttab,
|
||||
int st_len,
|
||||
char *title,
|
||||
int prefer_self) /* when equal print only self time */
|
||||
{
|
||||
int i;
|
||||
ufunc_T *fp;
|
||||
|
||||
fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
|
||||
fprintf(fd, "count total (s) self (s) function\n");
|
||||
for (i = 0; i < 20 && i < st_len; ++i)
|
||||
{
|
||||
fp = sorttab[i];
|
||||
prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
|
||||
prefer_self);
|
||||
if (fp->uf_name[0] == K_SPECIAL)
|
||||
fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
|
||||
else
|
||||
fprintf(fd, " %s()\n", fp->uf_name);
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the count and times for one function or function line.
|
||||
*/
|
||||
static void
|
||||
prof_func_line(
|
||||
FILE *fd,
|
||||
int count,
|
||||
proftime_T *total,
|
||||
proftime_T *self,
|
||||
int prefer_self) /* when equal print only self time */
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
fprintf(fd, "%5d ", count);
|
||||
if (prefer_self && profile_equal(total, self))
|
||||
fprintf(fd, " ");
|
||||
else
|
||||
fprintf(fd, "%s ", profile_msg(total));
|
||||
if (!prefer_self && profile_equal(total, self))
|
||||
fprintf(fd, " ");
|
||||
else
|
||||
fprintf(fd, "%s ", profile_msg(self));
|
||||
}
|
||||
else
|
||||
fprintf(fd, " ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare function for total time sorting.
|
||||
*/
|
||||
static int
|
||||
prof_total_cmp(const void *s1, const void *s2)
|
||||
{
|
||||
ufunc_T *p1, *p2;
|
||||
|
||||
p1 = *(ufunc_T **)s1;
|
||||
p2 = *(ufunc_T **)s2;
|
||||
return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare function for self time sorting.
|
||||
*/
|
||||
static int
|
||||
prof_self_cmp(const void *s1, const void *s2)
|
||||
{
|
||||
ufunc_T *p1, *p2;
|
||||
|
||||
p1 = *(ufunc_T **)s1;
|
||||
p2 = *(ufunc_T **)s2;
|
||||
return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare profiling for entering a child or something else that is not
|
||||
* counted for the script/function itself.
|
||||
* Should always be called in pair with prof_child_exit().
|
||||
*/
|
||||
void
|
||||
prof_child_enter(
|
||||
proftime_T *tm) /* place to store waittime */
|
||||
{
|
||||
funccall_T *fc = current_funccal;
|
||||
|
||||
if (fc != NULL && fc->func->uf_profiling)
|
||||
profile_start(&fc->prof_child);
|
||||
script_prof_save(tm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take care of time spent in a child.
|
||||
* Should always be called after prof_child_enter().
|
||||
*/
|
||||
void
|
||||
prof_child_exit(
|
||||
proftime_T *tm) /* where waittime was stored */
|
||||
{
|
||||
funccall_T *fc = current_funccal;
|
||||
|
||||
if (fc != NULL && fc->func->uf_profiling)
|
||||
{
|
||||
profile_end(&fc->prof_child);
|
||||
profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */
|
||||
profile_add(&fc->func->uf_tm_children, &fc->prof_child);
|
||||
profile_add(&fc->func->uf_tml_children, &fc->prof_child);
|
||||
}
|
||||
script_prof_restore(tm);
|
||||
}
|
||||
|
||||
#endif /* FEAT_PROFILE */
|
||||
|
||||
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||
@@ -3574,71 +3427,6 @@ get_func_line(
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if defined(FEAT_PROFILE) || defined(PROTO)
|
||||
/*
|
||||
* Called when starting to read a function line.
|
||||
* "sourcing_lnum" must be correct!
|
||||
* When skipping lines it may not actually be executed, but we won't find out
|
||||
* until later and we need to store the time now.
|
||||
*/
|
||||
void
|
||||
func_line_start(void *cookie)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
|
||||
if (fp->uf_profiling && sourcing_lnum >= 1
|
||||
&& sourcing_lnum <= fp->uf_lines.ga_len)
|
||||
{
|
||||
fp->uf_tml_idx = sourcing_lnum - 1;
|
||||
/* Skip continuation lines. */
|
||||
while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
|
||||
--fp->uf_tml_idx;
|
||||
fp->uf_tml_execed = FALSE;
|
||||
profile_start(&fp->uf_tml_start);
|
||||
profile_zero(&fp->uf_tml_children);
|
||||
profile_get_wait(&fp->uf_tml_wait);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when actually executing a function line.
|
||||
*/
|
||||
void
|
||||
func_line_exec(void *cookie)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
|
||||
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
|
||||
fp->uf_tml_execed = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when done with a function line.
|
||||
*/
|
||||
void
|
||||
func_line_end(void *cookie)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
|
||||
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
|
||||
{
|
||||
if (fp->uf_tml_execed)
|
||||
{
|
||||
++fp->uf_tml_count[fp->uf_tml_idx];
|
||||
profile_end(&fp->uf_tml_start);
|
||||
profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start);
|
||||
profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start);
|
||||
profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start,
|
||||
&fp->uf_tml_children);
|
||||
}
|
||||
fp->uf_tml_idx = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return TRUE if the currently active function should be ended, because a
|
||||
* return was encountered or an error occurred. Used inside a ":while".
|
||||
|
Reference in New Issue
Block a user