summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-07-13 22:59:32 +0200
committerBram Moolenaar <Bram@vim.org>2019-07-13 22:59:32 +0200
commitfa55cfc69d2b14761e2a8bd85bc1e0d82df770aa (patch)
tree3420b78d3aa0d58695f9a660592b655ac2f22fb1
parentd5abb4c87727eecb71b0e8ffdda60fc9598272f3 (diff)
patch 8.1.1684: profiling functionality is spread outv8.1.1684
Problem: Profiling functionality is spread out. Solution: Put profiling functionality in profiling.c. (Yegappan Lakshmanan, closes #4666)
-rw-r--r--Filelist1
-rw-r--r--src/Make_cyg_ming.mak1
-rw-r--r--src/Make_dice.mak4
-rw-r--r--src/Make_manx.mak6
-rw-r--r--src/Make_morph.mak1
-rw-r--r--src/Make_mvc.mak4
-rw-r--r--src/Make_sas.mak5
-rw-r--r--src/Make_vms.mms23
-rw-r--r--src/Makefile11
-rw-r--r--src/README.md3
-rw-r--r--src/ex_cmds2.c505
-rw-r--r--src/globals.h3
-rw-r--r--src/profiler.c679
-rw-r--r--src/proto.h3
-rw-r--r--src/proto/ex_cmds2.pro24
-rw-r--r--src/proto/profiler.pro34
-rw-r--r--src/proto/userfunc.pro3
-rw-r--r--src/structs.h51
-rw-r--r--src/userfunc.c224
-rw-r--r--src/version.c2
20 files changed, 832 insertions, 755 deletions
diff --git a/Filelist b/Filelist
index ff40389820..6e90d21eba 100644
--- a/Filelist
+++ b/Filelist
@@ -80,6 +80,7 @@ SRC_ALL = \
src/option.h \
src/popupmnu.c \
src/popupwin.c \
+ src/profiler.c \
src/quickfix.c \
src/regexp.c \
src/regexp_nfa.c \
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index d0769c39ee..b689df8ad6 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -752,6 +752,7 @@ OBJ = \
$(OUTDIR)/pathdef.o \
$(OUTDIR)/popupmnu.o \
$(OUTDIR)/popupwin.o \
+ $(OUTDIR)/profiler.o \
$(OUTDIR)/quickfix.o \
$(OUTDIR)/regexp.o \
$(OUTDIR)/screen.o \
diff --git a/src/Make_dice.mak b/src/Make_dice.mak
index 440955eb34..f95262ebb5 100644
--- a/src/Make_dice.mak
+++ b/src/Make_dice.mak
@@ -71,6 +71,7 @@ SRC = \
option.c \
os_amiga.c \
popupmnu.c \
+ profiler.c \
quickfix.c \
regexp.c \
screen.c \
@@ -134,6 +135,7 @@ OBJ = o/arabic.o \
o/option.o \
o/os_amiga.o \
o/popupmnu.o \
+ o/profiler.o \
o/quickfix.o \
o/regexp.o \
o/screen.o \
@@ -266,6 +268,8 @@ o/os_amiga.o: os_amiga.c $(SYMS) os_amiga.h
o/popupmnu.o: popupmnu.c $(SYMS)
+o/profiler.o: profiler.c $(SYMS)
+
o/quickfix.o: quickfix.c $(SYMS)
o/regexp.o: regexp.c $(SYMS) regexp.h
diff --git a/src/Make_manx.mak b/src/Make_manx.mak
index 211d8ccebf..e3babe567d 100644
--- a/src/Make_manx.mak
+++ b/src/Make_manx.mak
@@ -81,6 +81,7 @@ SRC = arabic.c \
option.c \
os_amiga.c \
popupmnu.c \
+ profiler.c \
quickfix.c \
regexp.c \
screen.c \
@@ -146,6 +147,7 @@ OBJ = obj/arabic.o \
obj/option.o \
obj/os_amiga.o \
obj/popupmnu.o \
+ obj/profiler.o \
obj/quickfix.o \
obj/regexp.o \
obj/screen.o \
@@ -209,6 +211,7 @@ PRO = proto/arabic.pro \
proto/option.pro \
proto/os_amiga.pro \
proto/popupmnu.pro \
+ proto/profiler.pro \
proto/quickfix.pro \
proto/regexp.pro \
proto/screen.pro \
@@ -410,6 +413,9 @@ obj/os_amiga.o: os_amiga.c
obj/popupmnu.o: popupmnu.c
$(CCSYM) $@ popupmnu.c
+obj/profiler.o: profiler.c
+ $(CCSYM) $@ profiler.c
+
obj/quickfix.o: quickfix.c
$(CCSYM) $@ quickfix.c
diff --git a/src/Make_morph.mak b/src/Make_morph.mak
index 1eb5ff52d7..7bd39faa3e 100644
--- a/src/Make_morph.mak
+++ b/src/Make_morph.mak
@@ -69,6 +69,7 @@ SRC = arabic.c \
option.c \
os_amiga.c \
popupmnu.c \
+ profiler.c \
quickfix.c \
regexp.c \
screen.c \
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 04e566bbbc..4a6aaa995f 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -761,6 +761,7 @@ OBJ = \
$(OUTDIR)\pathdef.obj \
$(OUTDIR)\popupmnu.obj \
$(OUTDIR)\popupwin.obj \
+ $(OUTDIR)\profiler.obj \
$(OUTDIR)\quickfix.obj \
$(OUTDIR)\regexp.obj \
$(OUTDIR)\screen.obj \
@@ -1595,6 +1596,8 @@ $(OUTDIR)/popupmnu.obj: $(OUTDIR) popupmnu.c $(INCL)
$(OUTDIR)/popupwin.obj: $(OUTDIR) popupwin.c $(INCL)
+$(OUTDIR)/profiler.obj: $(OUTDIR) profiler.c $(INCL)
+
$(OUTDIR)/quickfix.obj: $(OUTDIR) quickfix.c $(INCL)
$(OUTDIR)/regexp.obj: $(OUTDIR) regexp.c regexp_nfa.c $(INCL)
@@ -1763,6 +1766,7 @@ proto.h: \
proto/os_win32.pro \
proto/popupmnu.pro \
proto/popupwin.pro \
+ proto/profiler.pro \
proto/quickfix.pro \
proto/regexp.pro \
proto/screen.pro \
diff --git a/src/Make_sas.mak b/src/Make_sas.mak
index 7090119d75..607f48448c 100644
--- a/src/Make_sas.mak
+++ b/src/Make_sas.mak
@@ -134,6 +134,7 @@ SRC = \
option.c \
os_amiga.c \
popupmnu.c \
+ profiler.c \
quickfix.c \
regexp.c \
screen.c \
@@ -198,6 +199,7 @@ OBJ = \
option.o \
os_amiga.o \
popupmnu.o \
+ profiler.o \
quickfix.o \
regexp.o \
screen.o \
@@ -262,6 +264,7 @@ PRO = \
proto/option.pro \
proto/os_amiga.pro \
proto/popupmnu.pro \
+ proto/profiler.pro \
proto/quickfix.pro \
proto/regexp.pro \
proto/screen.pro \
@@ -425,6 +428,8 @@ os_amiga.o: os_amiga.c
proto/os_amiga.pro: os_amiga.c
popupmnu.o: popupmnu.c
proto/popupmnu.pro: popupmnu.c
+profiler.o: profiler.c
+proto/profiler.pro: profiler.c
quickfix.o: quickfix.c
proto/quickfix.pro: quickfix.c
regexp.o: regexp.c
diff --git a/src/Make_vms.mms b/src/Make_vms.mms
index f01d325c0a..b7063e158d 100644
--- a/src/Make_vms.mms
+++ b/src/Make_vms.mms
@@ -313,10 +313,10 @@ SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c change.c charset.c \
if_cscope.c if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c \
hardcopy.c hashtab.c indent.c insexpand.c json.c list.c main.c mark.c \
menu.c mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c \
- normal.c ops.c option.c popupmnu.c popupwin.c, quickfix.c regexp.c search.c \
- sha256.c sign.c spell.c spellfile.c syntax.c tag.c term.c termlib.c \
- textprop.c ui.c undo.c usercmd.c userfunc.c version.c screen.c \
- window.c os_unix.c os_vms.c pathdef.c \
+ normal.c ops.c option.c popupmnu.c popupwin.c profiler.c quickfix.c \
+ regexp.c search.c sha256.c sign.c spell.c spellfile.c syntax.c tag.c \
+ term.c termlib.c textprop.c ui.c undo.c usercmd.c userfunc.c \
+ version.c screen.c window.c os_unix.c os_vms.c pathdef.c \
$(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \
$(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC)
@@ -327,11 +327,12 @@ OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj change.
fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \
indent.obj insexpand.obj json.obj list.obj main.obj mark.obj \
menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
- move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj popupwin.obj\
- quickfix.obj regexp.obj search.obj sha256.obj sign.obj spell.obj \
- spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \
- ui.obj undo.obj usercmd.obj userfunc.obj screen.obj version.obj \
- window.obj os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \
+ move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj \
+ popupwin.obj profiler.obj quickfix.obj regexp.obj search.obj \
+ sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj \
+ term.obj termlib.obj textprop.obj ui.obj undo.obj usercmd.obj \
+ userfunc.obj screen.obj version.obj window.obj os_unix.obj os_vms.obj \
+ pathdef.obj if_mzsch.obj \
$(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \
$(RUBY_OBJ) $(HANGULIN_OBJ) $(MZSCH_OBJ) $(XDIFF_OBJ)
@@ -692,6 +693,10 @@ popupwin.obj : popupwin.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h \
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
globals.h
+profiler.obj : profiler.c vim.h [.auto]config.h feature.h os_unix.h \
+ ascii.h keymap.h term.h macros.h structs.h regexp.h \
+ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
+ globals.h
quickfix.obj : quickfix.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h \
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
diff --git a/src/Makefile b/src/Makefile
index 9c4a42893b..3f91e5bf1f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -521,6 +521,7 @@ CClink = $(CC)
# gpm - For mouse support on Linux console via gpm
# Uncomment this when you do not want to include gpm support, even
# though you have gpm libraries and includes.
+# For Debian/Ubuntu gpm support requires the libgpm-dev package.
#CONF_OPT_GPM = --disable-gpm
# sysmouse - For mouse support on FreeBSD and DragonFly console via sysmouse
@@ -1626,6 +1627,7 @@ BASIC_SRC = \
auto/pathdef.c \
popupmnu.c \
popupwin.c \
+ profiler.c \
pty.c \
quickfix.c \
regexp.c \
@@ -1742,6 +1744,7 @@ OBJ_COMMON = \
objects/pathdef.o \
objects/popupmnu.o \
objects/popupwin.o \
+ objects/profiler.o \
objects/pty.o \
objects/quickfix.o \
objects/regexp.o \
@@ -1883,6 +1886,7 @@ PRO_AUTO = \
os_unix.pro \
popupmnu.pro \
popupwin.pro \
+ profiler.pro \
pty.pro \
quickfix.pro \
regexp.pro \
@@ -3222,6 +3226,9 @@ objects/popupmnu.o: popupmnu.c
objects/popupwin.o: popupwin.c
$(CCC) -o $@ popupwin.c
+objects/profiler.o: profiler.c
+ $(CCC) -o $@ profiler.c
+
objects/pty.o: pty.c
$(CCC) -o $@ pty.c
@@ -3633,6 +3640,10 @@ objects/popupwin.o: popupwin.c vim.h protodef.h auto/config.h feature.h os_unix.
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
+objects/profiler.o: profiler.c vim.h protodef.h auto/config.h feature.h os_unix.h \
+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
+ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
+ proto.h globals.h
objects/pty.o: pty.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
diff --git a/src/README.md b/src/README.md
index ff9f93ac6d..87361097fe 100644
--- a/src/README.md
+++ b/src/README.md
@@ -44,13 +44,14 @@ menu.c | menus
message.c | (error) messages
ops.c | handling operators ("d", "y", "p")
option.c | options
+profiler.c | vim script profiler
quickfix.c | quickfix commands (":make", ":cn")
regexp.c | pattern matching
screen.c | updating the windows
search.c | pattern searching
sign.c | signs
spell.c | spell checking
-syntax.c | syntax and other highlighting
+syntax.c | syntax and other highlighting
tag.c | tags
term.c | terminal handling, termcap codes
undo.c | undo and redo
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index fb26b2aa4f..77ff08cf7c 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -16,215 +16,7 @@
static void cmd_source(char_u *fname, exarg_T *eap);
-#ifdef FEAT_EVAL
-/* Growarray to store info about already sourced scripts.
- * For Unix also store the dev/ino, so that we don't have to stat() each
- * script when going through the list. */
-typedef struct scriptitem_S
-{
- char_u *sn_name;
-# ifdef UNIX
- int sn_dev_valid;
- dev_t sn_dev;
- ino_t sn_ino;
-# endif
-# ifdef FEAT_PROFILE
- int sn_prof_on; /* TRUE when script is/was profiled */
- int sn_pr_force; /* forceit: profile functions in this script */
- proftime_T sn_pr_child; /* time set when going into first child */
- int sn_pr_nest; /* nesting for sn_pr_child */
- /* profiling the script as a whole */
- int sn_pr_count; /* nr of times sourced */
- proftime_T sn_pr_total; /* time spent in script + children */
- proftime_T sn_pr_self; /* time spent in script itself */
- proftime_T sn_pr_start; /* time at script start */
- proftime_T sn_pr_children; /* time in children after script start */
- /* profiling the script per line */
- garray_T sn_prl_ga; /* things stored for every line */
- proftime_T sn_prl_start; /* start time for current line */
- proftime_T sn_prl_children; /* time spent in children for this line */
- proftime_T sn_prl_wait; /* wait start time for current line */
- int sn_prl_idx; /* index of line being timed; -1 if none */
- int sn_prl_execed; /* line being timed was executed */
-# endif
-} scriptitem_T;
-
-static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
-#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
-
-# ifdef FEAT_PROFILE
-/* Struct used in sn_prl_ga for every line of a script. */
-typedef struct sn_prl_S
-{
- int snp_count; /* nr of times line was executed */
- proftime_T sn_prl_total; /* time spent in a line + children */
- proftime_T sn_prl_self; /* time spent in a line itself */
-} sn_prl_T;
-
-# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
-# endif
-#endif
-
#if defined(FEAT_EVAL) || defined(PROTO)
-# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
-/*
- * Store the current time in "tm".
- */
- void
-profile_start(proftime_T *tm)
-{
-# ifdef MSWIN
- QueryPerformanceCounter(tm);
-# else
- gettimeofday(tm, NULL);
-# endif
-}
-
-/*
- * Compute the elapsed time from "tm" till now and store in "tm".
- */
- void
-profile_end(proftime_T *tm)
-{
- proftime_T now;
-
-# ifdef MSWIN
- QueryPerformanceCounter(&now);
- tm->QuadPart = now.QuadPart - tm->QuadPart;
-# else
- gettimeofday(&now, NULL);
- tm->tv_usec = now.tv_usec - tm->tv_usec;
- tm->tv_sec = now.tv_sec - tm->tv_sec;
- if (tm->tv_usec < 0)
- {
- tm->tv_usec += 1000000;
- --tm->tv_sec;
- }
-# endif
-}
-
-/*
- * Subtract the time "tm2" from "tm".
- */
- void
-profile_sub(proftime_T *tm, proftime_T *tm2)
-{
-# ifdef MSWIN
- tm->QuadPart -= tm2->QuadPart;
-# else
- tm->tv_usec -= tm2->tv_usec;
- tm->tv_sec -= tm2->tv_sec;
- if (tm->tv_usec < 0)
- {
- tm->tv_usec += 1000000;
- --tm->tv_sec;
- }
-# endif
-}
-
-/*
- * Return a string that represents the time in "tm".
- * Uses a static buffer!
- */
- char *
-profile_msg(proftime_T *tm)
-{
- static char buf[50];
-
-# ifdef MSWIN
- LARGE_INTEGER fr;
-
- QueryPerformanceFrequency(&fr);
- sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
-# else
- sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
-# endif
- return buf;
-}
-
-# if defined(FEAT_FLOAT) || defined(PROTO)
-/*
- * Return a float that represents the time in "tm".
- */
- float_T
-profile_float(proftime_T *tm)
-{
-# ifdef MSWIN
- LARGE_INTEGER fr;
-
- QueryPerformanceFrequency(&fr);
- return (float_T)tm->QuadPart / (float_T)fr.QuadPart;
-# else
- return (float_T)tm->tv_sec + (float_T)tm->tv_usec / 1000000.0;
-# endif
-}
-# endif
-
-/*
- * Put the time "msec" past now in "tm".
- */
- void
-profile_setlimit(long msec, proftime_T *tm)
-{
- if (msec <= 0) /* no limit */
- profile_zero(tm);
- else
- {
-# ifdef MSWIN
- LARGE_INTEGER fr;
-
- QueryPerformanceCounter(tm);
- QueryPerformanceFrequency(&fr);
- tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart);
-# else
- long usec;
-
- gettimeofday(tm, NULL);
- usec = (long)tm->tv_usec + (long)msec * 1000;
- tm->tv_usec = usec % 1000000L;
- tm->tv_sec += usec / 1000000L;
-# endif
- }
-}
-
-/*
- * Return TRUE if the current time is past "tm".
- */
- int
-profile_passed_limit(proftime_T *tm)
-{
- proftime_T now;
-
-# ifdef MSWIN
- if (tm->QuadPart == 0) /* timer was not set */
- return FALSE;
- QueryPerformanceCounter(&now);
- return (now.QuadPart > tm->QuadPart);
-# else
- if (tm->tv_sec == 0) /* timer was not set */
- return FALSE;
- gettimeofday(&now, NULL);
- return (now.tv_sec > tm->tv_sec
- || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec));
-# endif
-}
-
-/*
- * Set the time in "tm" to zero.
- */
- void
-profile_zero(proftime_T *tm)
-{
-# ifdef MSWIN
- tm->QuadPart = 0;
-# else
- tm->tv_usec = 0;
- tm->tv_sec = 0;
-# endif
-}
-
-# endif /* FEAT_PROFILE || FEAT_RELTIME */
-
# if defined(FEAT_TIMERS) || defined(PROTO)
static timer_T *first_timer = NULL;
static long last_timer_id = 0;
@@ -603,270 +395,11 @@ timer_free_all()
# endif
# endif
-#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT) && defined(FEAT_PROFILE)
-# if defined(HAVE_MATH_H)
-# include <math.h>
-# endif
-
-/*
- * Divide the time "tm" by "count" and store in "tm2".
- */
- void
-profile_divide(proftime_T *tm, int count, proftime_T *tm2)
-{
- if (count == 0)
- profile_zero(tm2);
- else
- {
-# ifdef MSWIN
- tm2->QuadPart = tm->QuadPart / count;
-# else
- double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count;
-
- tm2->tv_sec = floor(usec / 1000000.0);
- tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0));
-# endif
- }
-}
-#endif
-
# if defined(FEAT_PROFILE) || defined(PROTO)
/*
- * Functions for profiling.
- */
-static void script_dump_profile(FILE *fd);
-static proftime_T prof_wait_time;
-
-/*
- * Add the time "tm2" to "tm".
- */
- void
-profile_add(proftime_T *tm, proftime_T *tm2)
-{
-# ifdef MSWIN
- tm->QuadPart += tm2->QuadPart;
-# else
- tm->tv_usec += tm2->tv_usec;
- tm->tv_sec += tm2->tv_sec;
- if (tm->tv_usec >= 1000000)
- {
- tm->tv_usec -= 1000000;
- ++tm->tv_sec;
- }
-# endif
-}
-
-/*
- * Add the "self" time from the total time and the children's time.
- */
- void
-profile_self(proftime_T *self, proftime_T *total, proftime_T *children)
-{
- /* Check that the result won't be negative. Can happen with recursive
- * calls. */
-#ifdef MSWIN
- if (total->QuadPart <= children->QuadPart)
- return;
-#else
- if (total->tv_sec < children->tv_sec
- || (total->tv_sec == children->tv_sec
- && total->tv_usec <= children->tv_usec))
- return;
-#endif
- profile_add(self, total);
- profile_sub(self, children);
-}
-
-/*
- * Get the current waittime.
- */
- void
-profile_get_wait(proftime_T *tm)
-{
- *tm = prof_wait_time;
-}
-
-/*
- * Subtract the passed waittime since "tm" from "tma".
- */
- void
-profile_sub_wait(proftime_T *tm, proftime_T *tma)
-{
- proftime_T tm3 = prof_wait_time;
-
- profile_sub(&tm3, tm);
- profile_sub(tma, &tm3);
-}
-
-/*
- * Return TRUE if "tm1" and "tm2" are equal.
- */
- int
-profile_equal(proftime_T *tm1, proftime_T *tm2)
-{
-# ifdef MSWIN
- return (tm1->QuadPart == tm2->QuadPart);
-# else
- return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec);
-# endif
-}
-
-/*
- * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
- */
- int
-profile_cmp(const proftime_T *tm1, const proftime_T *tm2)
-{
-# ifdef MSWIN
- return (int)(tm2->QuadPart - tm1->QuadPart);
-# else
- if (tm1->tv_sec == tm2->tv_sec)
- return tm2->tv_usec - tm1->tv_usec;
- return tm2->tv_sec - tm1->tv_sec;
-# endif
-}
-
-static char_u *profile_fname = NULL;
-static proftime_T pause_time;
-
-/*
- * ":profile cmd args"
- */
- void
-ex_profile(exarg_T *eap)
-{
- char_u *e;
- int len;
-
- e = skiptowhite(eap->arg);
- len = (int)(e - eap->arg);
- e = skipwhite(e);
-
- if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
- {
- vim_free(profile_fname);
- profile_fname = expand_env_save_opt(e, TRUE);
- do_profiling = PROF_YES;
- profile_zero(&prof_wait_time);
- set_vim_var_nr(VV_PROFILING, 1L);
- }
- else if (do_profiling == PROF_NONE)
- emsg(_("E750: First use \":profile start {fname}\""));
- else if (STRCMP(eap->arg, "pause") == 0)
- {
- if (do_profiling == PROF_YES)
- profile_start(&pause_time);
- do_profiling = PROF_PAUSED;
- }
- else if (STRCMP(eap->arg, "continue") == 0)
- {
- if (do_profiling == PROF_PAUSED)
- {
- profile_end(&pause_time);
- profile_add(&prof_wait_time, &pause_time);
- }
- do_profiling = PROF_YES;
- }
- else
- {
- /* The rest is similar to ":breakadd". */
- ex_breakadd(eap);
- }
-}
-
-/* Command line expansion for :profile. */
-static enum
-{
- PEXP_SUBCMD, /* expand :profile sub-commands */
- PEXP_FUNC /* expand :profile func {funcname} */
-} pexpand_what;
-
-static char *pexpand_cmds[] = {
- "start",
-#define PROFCMD_START 0
- "pause",
-#define PROFCMD_PAUSE 1
- "continue",
-#define PROFCMD_CONTINUE 2
- "func",
-#define PROFCMD_FUNC 3
- "file",
-#define PROFCMD_FILE 4
- NULL
-#define PROFCMD_LAST 5
-};
-
-/*
- * Function given to ExpandGeneric() to obtain the profile command
- * specific expansion.
- */
- char_u *
-get_profile_name(expand_T *xp UNUSED, int idx)
-{
- switch (pexpand_what)
- {
- case PEXP_SUBCMD:
- return (char_u *)pexpand_cmds[idx];
- /* case PEXP_FUNC: TODO */
- default:
- return NULL;
- }
-}
-
-/*
- * Handle command line completion for :profile command.
- */
- void
-set_context_in_profile_cmd(expand_T *xp, char_u *arg)
-{
- char_u *end_subcmd;
-
- /* Default: expand subcommands. */
- xp->xp_context = EXPAND_PROFILE;
- pexpand_what = PEXP_SUBCMD;
- xp->xp_pattern = arg;
-
- end_subcmd = skiptowhite(arg);
- if (*end_subcmd == NUL)
- return;
-
- if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0)
- {
- xp->xp_context = EXPAND_FILES;
- xp->xp_pattern = skipwhite(end_subcmd);
- return;
- }
-
- /* TODO: expand function names after "func" */
- xp->xp_context = EXPAND_NOTHING;
-}
-
-/*
- * Dump the profiling info.
- */
- void
-profile_dump(void)
-{
- FILE *fd;
-
- if (profile_fname != NULL)
- {
- fd = mch_fopen((char *)profile_fname, "w");
- if (fd == NULL)
- semsg(_(e_notopen), profile_fname);
- else
- {
- script_dump_profile(fd);
- func_dump_profile(fd);
- fclose(fd);
- }
- }
-}
-
-/*
* Start profiling script "fp".
*/
- static void
+ void
script_do_profile(scriptitem_T *si)
{
si->sn_pr_count = 0;
@@ -918,31 +451,10 @@ script_prof_restore(proftime_T *tm)
}
}
-static proftime_T inchar_time;
-
-/*
- * Called when starting to wait for the user to type a character.
- */
- void
-prof_inchar_enter(void)
-{
- profile_start(&inchar_time);
-}
-
-/*
- * Called when finished waiting for the user to type a character.
- */
- void
-prof_inchar_exit(void)
-{
- profile_end(&inchar_time);
- profile_add(&prof_wait_time, &inchar_time);
-}
-
/*
* Dump the profiling results for all scripts in file "fd".
*/
- static void
+ void
script_dump_profile(FILE *fd)
{
int id;
@@ -1016,19 +528,6 @@ script_dump_profile(FILE *fd)
}
}
}
-
-/*
- * Return TRUE when a function defined in the current script should be
- * profiled.
- */
- int
-prof_def_func(void)
-{
- if (current_sctx.sc_sid > 0)
- return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
- return FALSE;
-}
-
# endif
#endif
diff --git a/src/globals.h b/src/globals.h
index 3562b5ee6c..0c2df36b8e 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -252,6 +252,9 @@ EXTERN int debug_backtrace_level INIT(= 0); /* breakpoint backtrace level */
# ifdef FEAT_PROFILE
EXTERN int do_profiling INIT(= PROF_NONE); /* PROF_ values */
# endif
+EXTERN garray_T script_items INIT(= {0 COMMA 0 COMMA sizeof(scriptitem_T) COMMA 4 COMMA NULL});
+#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
+#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
/*
* The exception currently being thrown. Used to pass an exception to
diff --git a/src/profiler.c b/src/profiler.c
new file mode 100644
index 0000000000..dab21bceb4
--- /dev/null
+++ b/src/profiler.c
@@ -0,0 +1,679 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * profiler.c: vim script profiler
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
+/*
+ * Store the current time in "tm".
+ */
+ void
+profile_start(proftime_T *tm)
+{
+# ifdef MSWIN
+ QueryPerformanceCounter(tm);
+# else
+ gettimeofday(tm, NULL);
+# endif
+}
+
+/*
+ * Compute the elapsed time from "tm" till now and store in "tm".
+ */
+ void
+profile_end(proftime_T *tm)
+{
+ proftime_T now;
+
+# ifdef MSWIN
+ QueryPerformanceCounter(&now);
+ tm->QuadPart = now.QuadPart - tm->QuadPart;
+# else
+ gettimeofday(&now, NULL);
+ tm->tv_usec = now.tv_usec - tm->tv_usec;
+ tm->tv_sec = now.tv_sec - tm->tv_sec;
+ if (tm->tv_usec < 0)
+ {
+ tm->tv_usec += 1000000;
+ --tm->tv_sec;
+ }
+# endif
+}
+
+/*
+ * Subtract the time "tm2" from "tm".
+ */
+ void
+profile_sub(proftime_T *tm, proftime_T *tm2)
+{
+# ifdef MSWIN
+ tm->QuadPart -= tm2->QuadPart;
+# else
+ tm->tv_usec -= tm2->tv_usec;
+ tm->tv_sec -= tm2->tv_sec;
+ if (tm->tv_usec < 0)
+ {
+ tm->tv_usec += 1000000;
+ --tm->tv_sec;
+ }
+# endif
+}
+
+/*
+ * Return a string that represents the time in "tm".
+ * Uses a static buffer!
+ */
+ char *
+profile_msg(proftime_T *tm)
+{
+ static char buf[50];
+
+# ifdef MSWIN
+ LARGE_INTEGER fr;
+
+ QueryPerformanceFrequency(&fr);
+ sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
+# else
+ sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
+# endif
+ return buf;
+}
+
+# if defined(FEAT_FLOAT) || defined(PROTO)
+/*
+ * Return a float that represents the time in "tm".
+ */
+ float_T
+profile_float(proftime_T *tm)
+{
+# ifdef MSWIN
+ LARGE_INTEGER fr;
+
+ QueryPerformanceFrequency(&fr);
+ return (float_T)tm->QuadPart / (float_T)fr.QuadPart;
+# else
+ return (float_T)tm->tv_sec + (float_T)tm->tv_usec / 1000000.0;
+# endif
+}
+# endif
+
+/*
+ * Put the time "msec" past now in "tm".
+ */
+ void
+profile_setlimit(long msec, proftime_T *tm)
+{
+ if (msec <= 0) /* no limit */
+ profile_zero(tm);
+ else
+ {
+# ifdef MSWIN
+ LARGE_INTEGER fr;
+
+ QueryPerformanceCounter(tm);
+ QueryPerformanceFrequency(&fr);
+ tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart);
+# else
+ long usec;
+
+ gettimeofday(tm, NULL);
+ usec = (long)tm->tv_usec + (long)msec * 1000;
+ tm->tv_usec = usec % 1000000L;
+ tm->tv_sec += usec / 1000000L;
+# endif
+ }
+}
+
+/*
+ * Return TRUE if the current time is past "tm".
+ */
+ int
+profile_passed_limit(proftime_T *tm)
+{
+ proftime_T now;
+
+# ifdef MSWIN
+ if (tm->QuadPart == 0) /* timer was not set */
+ return FALSE;
+ QueryPerformanceCounter(&now);
+ return (now.QuadPart > tm->QuadPart);
+# else
+ if (tm->tv_sec == 0) /* timer was not set */
+ return FALSE;
+ gettimeofday(&now, NULL);
+ return (now.tv_sec > tm->tv_sec
+ || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec));
+# endif
+}
+
+/*
+ * Set the time in "tm" to zero.
+ */
+ void
+profile_zero(proftime_T *tm)
+{
+# ifdef MSWIN
+ tm->QuadPart = 0;
+# else
+ tm->tv_usec = 0;
+ tm->tv_sec = 0;
+# endif
+}
+
+# endif /* FEAT_PROFILE || FEAT_RELTIME */
+
+#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT) && defined(FEAT_PROFILE)
+# if defined(HAVE_MATH_H)
+# include <math.h>
+# endif
+
+/*
+ * Divide the time "tm" by "count" and store in "tm2".
+ */
+ void
+profile_divide(proftime_T *tm, int count, proftime_T *tm2)
+{
+ if (count == 0)
+ profile_zero(tm2);
+ else
+ {
+# ifdef MSWIN
+ tm2->QuadPart = tm->QuadPart / count;
+# else
+ double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count;
+
+ tm2->tv_sec = floor(usec / 1000000.0);
+ tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0));
+# endif
+ }
+}
+#endif
+
+# if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Functions for profiling.
+ */
+static proftime_T prof_wait_time;
+