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)
diff --git a/src/userfunc.c b/src/userfunc.c
index 6bfe534..6d21b3f 100644
--- a/src/userfunc.c
+++ b/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_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 @@
}
}
+ funccall_T *
+get_current_funccal(void)
+{
+ return current_funccal;
+}
+
#if defined(EXITFREE) || defined(PROTO)
void
free_all_functions(void)
@@ -2762,36 +2760,6 @@
#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 @@
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 @@
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".