Mercurial > hg > xemacs-beta
diff src/profile.c @ 241:f955c73f5258 r20-5b19
Import from CVS: tag r20-5b19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:16:16 +0200 |
parents | e45d5e7c476e |
children | 8626e4521993 |
line wrap: on
line diff
--- a/src/profile.c Mon Aug 13 10:15:49 2007 +0200 +++ b/src/profile.c Mon Aug 13 10:16:16 2007 +0200 @@ -1,5 +1,6 @@ /* Why the hell is XEmacs so fucking slow? Copyright (C) 1996 Ben Wing. + Copyright (C) 1998 Free Software Foundation, Inc. This file is part of XEmacs. @@ -28,27 +29,35 @@ #include "syssignal.h" #include "systime.h" -/* +/* We implement our own profiling scheme so that we can determine + things like which Lisp functions are occupying the most time. Any + standard OS-provided profiling works on C functions, which is + somewhat useless. -We implement our own profiling scheme so that we can determine things -like which Lisp functions are occupying the most time. Any standard -OS-provided profiling works on C functions, which is somewhat useless. + The basic idea is simple. We set a profiling timer using setitimer + (ITIMER_PROF), which generates a SIGPROF every so often. (This + runs not in real time but rather when the process is executing or + the system is running on behalf of the process.) When the signal + goes off, we see what we're in, and add by 1 the count associated + with that function. -The basic idea is simple. We set a profiling timer using -setitimer (ITIMER_PROF), which generates a SIGPROF every so often. -\(This runs not in real time but rather when the process is executing -or the system is running on behalf of the process.) When the signal -goes off, we see what we're in, and add by 1 the count associated with -that function. + It would be nice to use the Lisp allocation mechanism etc. to keep + track of the profiling information, but we can't because that's not + safe, and trying to make it safe would be much more work than is + worth. + -It would be nice to use the Lisp allocation mechanism etc. to keep -track of the profiling information, but we can't because that's not -safe, and trying to make it safe would be much more work than is -worth. - -*/ + Jan 1998: In addition to this, I have added code to remember call + counts of Lisp funcalls. The profile_increase_call_count() + function is called from funcall_recording_as(), and serves to add + data to Vcall_count_profile_table. This mechanism is much simpler + and independent of the SIGPROF-driven one. It uses the Lisp + allocation mechanism normally, since it is not called from a + handler. It may even be useful to provide a way to turn on only + one profiling mechanism, but I haven't done so yet. --hniksic */ c_hashtable big_profile_table; +Lisp_Object Vcall_count_profile_table; int default_profiling_interval; @@ -69,6 +78,22 @@ enough to catch us while we're already in there. */ static volatile int inside_profiling; +/* Increase the value of OBJ in Vcall_count_profile_table hashtable. + If hashtable is nil, create it first. */ +void +profile_increase_call_count (Lisp_Object obj) +{ + Lisp_Object count; + + if (NILP (Vcall_count_profile_table)) + Vcall_count_profile_table = Fmake_hashtable (make_int (100), Qeq); + + count = Fgethash (obj, Vcall_count_profile_table, Qzero); + if (!INTP (count)) + count = Qzero; + Fputhash (obj, make_int (1 + XINT (count)), Vcall_count_profile_table); +} + static SIGTYPE sigprof_handler (int signo) { @@ -194,7 +219,7 @@ Lisp_Object accum; }; -static void +static int get_profiling_info_maphash (CONST void *void_key, void *void_val, void *void_closure) @@ -209,6 +234,7 @@ val = (EMACS_INT) void_val; closure->accum = Fcons (Fcons (key, make_int (val)), closure->accum); + return 0; } DEFUN ("get-profiling-info", Fget_profiling_info, 0, 0, 0, /* @@ -236,7 +262,7 @@ void (*markfun) (Lisp_Object); }; -static void +static int mark_profiling_info_maphash (CONST void *void_key, void *void_val, void *void_closure) @@ -245,6 +271,7 @@ CVOID_TO_LISP (key, void_key); (((struct mark_profiling_info_closure *) void_closure)->markfun) (key); + return 0; } void @@ -274,6 +301,8 @@ clrhash (big_profile_table); inside_profiling = 0; } + if (!NILP(Vcall_count_profile_table)) + Fclrhash (Vcall_count_profile_table); return Qnil; } @@ -306,6 +335,13 @@ */ ); default_profiling_interval = 1000; + DEFVAR_LISP ("call-count-profile-table", &Vcall_count_profile_table /* +The table where call-count information is stored by the profiling primitives. +This is a hashtable whose keys are funcallable objects, and whose + values are their call counts (integers). +*/ ); + Vcall_count_profile_table = Qnil; + inside_profiling = 0; QSin_redisplay = build_string ("(in redisplay)");