comparison src/profile.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents f955c73f5258
children 74fd4e045ea6
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
22 #include <config.h> 22 #include <config.h>
23 #include "lisp.h" 23 #include "lisp.h"
24 24
25 #include "backtrace.h" 25 #include "backtrace.h"
26 #include "bytecode.h" 26 #include "bytecode.h"
27 #include "elhash.h"
27 #include "hash.h" 28 #include "hash.h"
28 29
29 #include "syssignal.h" 30 #include "syssignal.h"
30 #include "systime.h" 31 #include "systime.h"
31 32
36 37
37 The basic idea is simple. We set a profiling timer using setitimer 38 The basic idea is simple. We set a profiling timer using setitimer
38 (ITIMER_PROF), which generates a SIGPROF every so often. (This 39 (ITIMER_PROF), which generates a SIGPROF every so often. (This
39 runs not in real time but rather when the process is executing or 40 runs not in real time but rather when the process is executing or
40 the system is running on behalf of the process.) When the signal 41 the system is running on behalf of the process.) When the signal
41 goes off, we see what we're in, and add by 1 the count associated 42 goes off, we see what we're in, and add 1 to the count associated
42 with that function. 43 with that function.
43 44
44 It would be nice to use the Lisp allocation mechanism etc. to keep 45 It would be nice to use the Lisp allocation mechanism etc. to keep
45 track of the profiling information, but we can't because that's not 46 track of the profiling information, but we can't because that's not
46 safe, and trying to make it safe would be much more work than is 47 safe, and trying to make it safe would be much more work than it's
47 worth. 48 worth.
48 49
49 50
50 Jan 1998: In addition to this, I have added code to remember call 51 Jan 1998: In addition to this, I have added code to remember call
51 counts of Lisp funcalls. The profile_increase_call_count() 52 counts of Lisp funcalls. The profile_increase_call_count()
52 function is called from funcall_recording_as(), and serves to add 53 function is called from Ffuncall(), and serves to add data to
53 data to Vcall_count_profile_table. This mechanism is much simpler 54 Vcall_count_profile_table. This mechanism is much simpler and
54 and independent of the SIGPROF-driven one. It uses the Lisp 55 independent of the SIGPROF-driven one. It uses the Lisp allocation
55 allocation mechanism normally, since it is not called from a 56 mechanism normally, since it is not called from a handler. It may
56 handler. It may even be useful to provide a way to turn on only 57 even be useful to provide a way to turn on only one profiling
57 one profiling mechanism, but I haven't done so yet. --hniksic */ 58 mechanism, but I haven't done so yet. --hniksic */
58 59
59 c_hashtable big_profile_table; 60 struct hash_table *big_profile_table;
60 Lisp_Object Vcall_count_profile_table; 61 Lisp_Object Vcall_count_profile_table;
61 62
62 int default_profiling_interval; 63 int default_profiling_interval;
63 64
64 int profiling_active; 65 int profiling_active;
76 the table while another routine is operating on it. We also set 77 the table while another routine is operating on it. We also set
77 inside_profiling in case the timeout between signal calls is short 78 inside_profiling in case the timeout between signal calls is short
78 enough to catch us while we're already in there. */ 79 enough to catch us while we're already in there. */
79 static volatile int inside_profiling; 80 static volatile int inside_profiling;
80 81
81 /* Increase the value of OBJ in Vcall_count_profile_table hashtable. 82 /* Increase the value of OBJ in Vcall_count_profile_table hash table.
82 If hashtable is nil, create it first. */ 83 If the hash table is nil, create it first. */
83 void 84 void
84 profile_increase_call_count (Lisp_Object obj) 85 profile_increase_call_count (Lisp_Object obj)
85 { 86 {
86 Lisp_Object count; 87 Lisp_Object count;
87 88
88 if (NILP (Vcall_count_profile_table)) 89 if (NILP (Vcall_count_profile_table))
89 Vcall_count_profile_table = Fmake_hashtable (make_int (100), Qeq); 90 Vcall_count_profile_table =
91 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
90 92
91 count = Fgethash (obj, Vcall_count_profile_table, Qzero); 93 count = Fgethash (obj, Vcall_count_profile_table, Qzero);
92 if (!INTP (count)) 94 if (!INTP (count))
93 count = Qzero; 95 count = Qzero;
94 Fputhash (obj, make_int (1 + XINT (count)), Vcall_count_profile_table); 96 Fputhash (obj, make_int (1 + XINT (count)), Vcall_count_profile_table);
115 fun = QSin_garbage_collection; 117 fun = QSin_garbage_collection;
116 else if (backtrace_list) 118 else if (backtrace_list)
117 { 119 {
118 fun = *backtrace_list->function; 120 fun = *backtrace_list->function;
119 121
120 if (!GC_SYMBOLP (fun) && !GC_COMPILED_FUNCTIONP (fun)) 122 if (!GC_SYMBOLP (fun) &&
121 fun = QSunknown; 123 !GC_COMPILED_FUNCTIONP (fun) &&
124 !GC_SUBRP (fun))
125 fun = QSunknown;
122 } 126 }
123 else 127 else
124 fun = QSprocessing_events_at_top_level; 128 fun = QSprocessing_events_at_top_level;
125 129
126 { 130 {
161 /* This function can GC */ 165 /* This function can GC */
162 int msecs; 166 int msecs;
163 struct itimerval foo; 167 struct itimerval foo;
164 168
165 /* #### The hash code can safely be called from a signal handler 169 /* #### The hash code can safely be called from a signal handler
166 except when it has to grow the hashtable. In this case, it calls 170 except when it has to grow the hash table. In this case, it calls
167 realloc(), which is not (in general) re-entrant. We just be 171 realloc(), which is not (in general) re-entrant. We'll just be
168 sleazy and make the table large enough that it (hopefully) won't 172 sleazy and make the table large enough that it (hopefully) won't
169 need to be realloc()ed. */ 173 need to be realloc()ed. */
170 if (!big_profile_table) 174 if (!big_profile_table)
171 big_profile_table = make_hashtable (10000); 175 big_profile_table = make_hash_table (10000);
176
172 if (NILP (microsecs)) 177 if (NILP (microsecs))
173 msecs = default_profiling_interval; 178 msecs = default_profiling_interval;
174 else 179 else
175 { 180 {
176 CHECK_NATNUM (microsecs); 181 CHECK_NATNUM (microsecs);
299 { 304 {
300 inside_profiling = 1; 305 inside_profiling = 1;
301 clrhash (big_profile_table); 306 clrhash (big_profile_table);
302 inside_profiling = 0; 307 inside_profiling = 0;
303 } 308 }
304 if (!NILP(Vcall_count_profile_table)) 309 if (!NILP (Vcall_count_profile_table))
305 Fclrhash (Vcall_count_profile_table); 310 Fclrhash (Vcall_count_profile_table);
306 return Qnil; 311 return Qnil;
307 } 312 }
308 313
309 DEFUN ("profiling-active-p", Fprofiling_active_p, 0, 0, 0, /* 314 DEFUN ("profiling-active-p", Fprofiling_active_p, 0, 0, 0, /*
326 331
327 void 332 void
328 vars_of_profile (void) 333 vars_of_profile (void)
329 { 334 {
330 DEFVAR_INT ("default-profiling-interval", &default_profiling_interval /* 335 DEFVAR_INT ("default-profiling-interval", &default_profiling_interval /*
331 Default time in microseconds between profiling queries. 336 Default CPU time in microseconds between profiling sampling.
332 Used when the argument to `start-profiling' is nil or omitted. 337 Used when the argument to `start-profiling' is nil or omitted.
333 Note that the time in question is CPU time (when the program is executing 338 Note that the time in question is CPU time (when the program is executing
334 or the kernel is executing on behalf of the program) and not real time. 339 or the kernel is executing on behalf of the program) and not real time.
335 */ ); 340 */ );
336 default_profiling_interval = 1000; 341 default_profiling_interval = 1000;
337 342
338 DEFVAR_LISP ("call-count-profile-table", &Vcall_count_profile_table /* 343 DEFVAR_LISP ("call-count-profile-table", &Vcall_count_profile_table /*
339 The table where call-count information is stored by the profiling primitives. 344 The table where call-count information is stored by the profiling primitives.
340 This is a hashtable whose keys are funcallable objects, and whose 345 This is a hash table whose keys are funcallable objects, and whose
341 values are their call counts (integers). 346 values are their call counts (integers).
342 */ ); 347 */ );
343 Vcall_count_profile_table = Qnil; 348 Vcall_count_profile_table = Qnil;
344 349
345 inside_profiling = 0; 350 inside_profiling = 0;
346 351