aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Hinz <mh.codebro@gmail.com>2015-04-14 20:28:08 +0200
committerMarco Hinz <mh.codebro@gmail.com>2015-11-10 02:49:47 +0100
commit1902ee52ef60d96f2ad043687a1e86bcf7be8aed (patch)
tree3e65c5fa9849f391cfa0227a25874a0d3798e968
parent588bf76650d6d645403e70437c649e7759430c05 (diff)
downloadrneovim-1902ee52ef60d96f2ad043687a1e86bcf7be8aed.tar.gz
rneovim-1902ee52ef60d96f2ad043687a1e86bcf7be8aed.tar.bz2
rneovim-1902ee52ef60d96f2ad043687a1e86bcf7be8aed.zip
Add ":profile stop"
This writes the logfile and stops profiling.
-rw-r--r--runtime/doc/repeat.txt3
-rw-r--r--src/nvim/eval.c45
-rw-r--r--src/nvim/eval.h41
-rw-r--r--src/nvim/ex_cmds2.c83
4 files changed, 115 insertions, 57 deletions
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index eae2c3867e..d029391c60 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -586,6 +586,9 @@ For example, to profile the one_script.vim script file: >
If {fname} already exists it will be silently overwritten.
The variable |v:profiling| is set to one.
+:prof[ile] stop
+ Write the logfile and stop profiling.
+
:prof[ile] pause
Don't profile until the following ":profile continue". Can be
used when doing something that should not be counted (e.g., an
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 8534cf5319..045d513a4a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -229,50 +229,11 @@ static int echo_attr = 0; /* attributes used for ":echo" */
#define GLV_QUIET TFN_QUIET /* no error messages */
#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */
-/*
- * Structure to hold info for a user function.
- */
-typedef struct ufunc ufunc_T;
-
-struct ufunc {
- int uf_varargs; /* variable nr of arguments */
- int uf_flags;
- int uf_calls; /* nr of active calls */
- garray_T uf_args; /* arguments */
- garray_T uf_lines; /* function lines */
- int uf_profiling; /* TRUE when func is being profiled */
- /* profiling the function as a whole */
- int uf_tm_count; /* nr of calls */
- proftime_T uf_tm_total; /* time spent in function + children */
- proftime_T uf_tm_self; /* time spent in function itself */
- proftime_T uf_tm_children; /* time spent in children this call */
- /* profiling the function per line */
- int *uf_tml_count; /* nr of times line was executed */
- proftime_T *uf_tml_total; /* time spent in a line + children */
- proftime_T *uf_tml_self; /* time spent in a line itself */
- proftime_T uf_tml_start; /* start time for current line */
- proftime_T uf_tml_children; /* time spent in children for this line */
- proftime_T uf_tml_wait; /* start wait time for current line */
- int uf_tml_idx; /* index of line being timed; -1 if none */
- int uf_tml_execed; /* line being timed was executed */
- scid_T uf_script_ID; /* ID of script where function was defined,
- used for s: variables */
- int uf_refcount; /* for numbered function: reference count */
- char_u uf_name[1]; /* name of function (actually longer); can
- start with <SNR>123_ (<SNR> is K_SPECIAL
- KS_EXTRA KE_SNR) */
-};
-
/* function flags */
#define FC_ABORT 1 /* abort function on error */
#define FC_RANGE 2 /* function accepts range */
#define FC_DICT 4 /* Dict function, uses "self" */
-/*
- * All user-defined functions are found in this hashtable.
- */
-static hashtab_T func_hashtab;
-
/* The names of packages that once were loaded are remembered. */
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
@@ -280,12 +241,6 @@ static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
static dict_T *first_dict = NULL; /* list of all dicts */
static list_T *first_list = NULL; /* list of all lists */
-/* From user function to hashitem and back. */
-static ufunc_T dumuf;
-#define UF2HIKEY(fp) ((fp)->uf_name)
-#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
-#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]
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 864daed716..8ccf71068c 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -5,6 +5,47 @@
#include "nvim/profile.h"
+// All user-defined functions are found in this hashtable.
+EXTERN hashtab_T func_hashtab;
+
+// Structure to hold info for a user function.
+typedef struct ufunc ufunc_T;
+
+struct ufunc {
+ int uf_varargs; ///< variable nr of arguments
+ int uf_flags;
+ int uf_calls; ///< nr of active calls
+ garray_T uf_args; ///< arguments
+ garray_T uf_lines; ///< function lines
+ int uf_profiling; ///< true when func is being profiled
+ // Profiling the function as a whole.
+ int uf_tm_count; ///< nr of calls
+ proftime_T uf_tm_total; ///< time spent in function + children
+ proftime_T uf_tm_self; ///< time spent in function itself
+ proftime_T uf_tm_children; ///< time spent in children this call
+ // Profiling the function per line.
+ int *uf_tml_count; ///< nr of times line was executed
+ proftime_T *uf_tml_total; ///< time spent in a line + children
+ proftime_T *uf_tml_self; ///< time spent in a line itself
+ proftime_T uf_tml_start; ///< start time for current line
+ proftime_T uf_tml_children; ///< time spent in children for this line
+ proftime_T uf_tml_wait; ///< start wait time for current line
+ int uf_tml_idx; ///< index of line being timed; -1 if none
+ int uf_tml_execed; ///< line being timed was executed
+ scid_T uf_script_ID; ///< ID of script where function was defined,
+ // used for s: variables
+ int uf_refcount; ///< for numbered function: reference count
+ char_u uf_name[1]; ///< name of function (actually longer); can
+ // start with <SNR>123_ (<SNR> is K_SPECIAL
+ // KS_EXTRA KE_SNR)
+};
+
+// From user function to hashitem and back.
+EXTERN ufunc_T dumuf;
+#define UF2HIKEY(fp) ((fp)->uf_name)
+#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
+#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
+
/* Defines for Vim variables. These must match vimvars[] in eval.c! */
enum {
VV_COUNT,
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 46bd8685d9..ba17423475 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -761,9 +761,14 @@ void ex_profile(exarg_T *eap)
do_profiling = PROF_YES;
profile_set_wait(profile_zero());
set_vim_var_nr(VV_PROFILING, 1L);
- } else if (do_profiling == PROF_NONE)
+ } else if (do_profiling == PROF_NONE) {
EMSG(_("E750: First use \":profile start {fname}\""));
- else if (STRCMP(eap->arg, "pause") == 0) {
+ } else if (STRCMP(eap->arg, "stop") == 0) {
+ profile_dump();
+ do_profiling = PROF_NONE;
+ set_vim_var_nr(VV_PROFILING, 0L);
+ profile_reset();
+ } else if (STRCMP(eap->arg, "pause") == 0) {
if (do_profiling == PROF_YES)
pause_time = profile_start();
do_profiling = PROF_PAUSED;
@@ -818,12 +823,13 @@ static enum {
} pexpand_what;
static char *pexpand_cmds[] = {
- "start",
- "pause",
"continue",
- "func",
- "file",
"dump",
+ "file",
+ "func",
+ "pause",
+ "start",
+ "stop",
NULL
};
@@ -887,10 +893,63 @@ void profile_dump(void)
}
}
-/*
- * Start profiling script "fp".
- */
-static void script_do_profile(scriptitem_T *si)
+/// Reset all profiling information.
+static void profile_reset(void)
+{
+ // Reset sourced files.
+ for (int id = 1; id <= script_items.ga_len; id++) {
+ scriptitem_T *si = &SCRIPT_ITEM(id);
+ if (si->sn_prof_on) {
+ si->sn_prof_on = 0;
+ si->sn_pr_force = 0;
+ si->sn_pr_child = profile_zero();
+ si->sn_pr_nest = 0;
+ si->sn_pr_count = 0;
+ si->sn_pr_total = profile_zero();
+ si->sn_pr_self = profile_zero();
+ si->sn_pr_start = profile_zero();
+ si->sn_pr_children = profile_zero();
+ ga_clear(&si->sn_prl_ga);
+ si->sn_prl_start = profile_zero();
+ si->sn_prl_children = profile_zero();
+ si->sn_prl_wait = profile_zero();
+ si->sn_prl_idx = -1;
+ si->sn_prl_execed = 0;
+ }
+ }
+
+ // Reset functions.
+ size_t n = func_hashtab.ht_used;
+ hashitem_T *hi = func_hashtab.ht_array;
+
+ for (; n > (size_t)0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ n--;
+ ufunc_T *uf = HI2UF(hi);
+ if (uf->uf_profiling) {
+ uf->uf_profiling = 0;
+ uf->uf_tm_count = 0;
+ uf->uf_tm_total = profile_zero();
+ uf->uf_tm_self = profile_zero();
+ uf->uf_tm_children = profile_zero();
+ uf->uf_tml_count = NULL;
+ uf->uf_tml_total = NULL;
+ uf->uf_tml_self = NULL;
+ uf->uf_tml_start = profile_zero();
+ uf->uf_tml_children = profile_zero();
+ uf->uf_tml_wait = profile_zero();
+ uf->uf_tml_idx = -1;
+ uf->uf_tml_execed = 0;
+ }
+ }
+ }
+
+ xfree(profile_fname);
+ profile_fname = NULL;
+}
+
+/// Start profiling a script.
+static void profile_init(scriptitem_T *si)
{
si->sn_pr_count = 0;
si->sn_pr_total = profile_zero();
@@ -2506,8 +2565,8 @@ do_source (
int forceit;
/* Check if we do profiling for this script. */
- if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit)) {
- script_do_profile(si);
+ if (!si->sn_prof_on && has_profiling(true, si->sn_name, &forceit)) {
+ profile_init(si);
si->sn_pr_force = forceit;
}
if (si->sn_prof_on) {