* src/profiler.c: Rename sample_profiler_* to profiler_cpu_* and
authorStefan Monnier <monnier@iro.umontreal.ca>
Tue, 25 Sep 2012 02:30:46 +0000 (22:30 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Tue, 25 Sep 2012 02:30:46 +0000 (22:30 -0400)
memory_profiler_* to profiler_memory_*.  Move sigprof_handler before
its first use, inside the PROFILER_CPU_SUPPORT conditional.

lisp/profiler.el
src/ChangeLog
src/alloc.c
src/lisp.h
src/profiler.c

index 90740a2..fb38b00 100644 (file)
@@ -579,30 +579,30 @@ Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started."
                                  nil t nil nil "cpu"))))
   (cl-ecase mode
     (cpu
-     (sample-profiler-start profiler-sample-interval)
+     (profiler-cpu-start profiler-sample-interval)
      (message "CPU profiler started"))
     (mem
-     (memory-profiler-start)
+     (profiler-memory-start)
      (message "Memory profiler started"))
     (cpu+mem
-     (sample-profiler-start profiler-sample-interval)
-     (memory-profiler-start)
+     (profiler-cpu-start profiler-sample-interval)
+     (profiler-memory-start)
      (message "CPU and memory profiler started"))))
 
 (defun profiler-stop ()
   "Stop started profilers.  Profiler logs will be kept."
   (interactive)
   (cond
-   ((and (sample-profiler-running-p)
-        (memory-profiler-running-p))
-    (sample-profiler-stop)
-    (memory-profiler-stop)
+   ((and (profiler-cpu-running-p)
+        (profiler-memory-running-p))
+    (profiler-cpu-stop)
+    (profiler-memory-stop)
     (message "CPU and memory profiler stopped"))
-   ((sample-profiler-running-p)
-    (sample-profiler-stop)
+   ((profiler-cpu-running-p)
+    (profiler-cpu-stop)
     (message "CPU profiler stopped"))
-   ((memory-profiler-running-p)
-    (memory-profiler-stop)
+   ((profiler-memory-running-p)
+    (profiler-memory-stop)
     (message "Memory profiler stopped"))
    (t
     (error "No profilers started"))))
@@ -610,19 +610,19 @@ Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started."
 (defun profiler-reset ()
   "Reset profiler log."
   (interactive)
-  (ignore (sample-profiler-log))
-  (ignore (memory-profiler-log))
+  (ignore (profiler-cpu-log))
+  (ignore (profiler-memory-log))
   t)
 
 (defun profiler--report-cpu ()
-  (let ((log (sample-profiler-log)))
+  (let ((log (profiler-cpu-log)))
     (when log
       (puthash 'type 'cpu log)
       (puthash 'timestamp (current-time) log)
       (profiler-report-log log))))
 
 (defun profiler--report-memory ()
-  (let ((log (memory-profiler-log)))
+  (let ((log (profiler-memory-log)))
     (when log
       (puthash 'type 'memory log)
       (puthash 'timestamp (current-time) log)
@@ -647,19 +647,19 @@ Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started."
 (cl-defmacro with-sample-profiling ((&key interval) &rest body)
   `(unwind-protect
        (progn
-         (ignore (sample-profiler-log))
-         (sample-profiler-start ,interval)
+         (ignore (profiler-cpu-log))
+         (profiler-cpu-start ,interval)
          ,@body)
-     (sample-profiler-stop)
+     (profiler-cpu-stop)
      (profiler--report-cpu)))
 
 (defmacro with-memory-profiling (&rest body)
   `(unwind-protect
        (progn
-         (ignore (memory-profiler-log))
-         (memory-profiler-start)
+         (ignore (profiler-memory-log))
+         (profiler-memory-start)
          ,@body)
-     (memory-profiler-stop)
+     (profiler-memory-stop)
      (profiler--report-memory)))
 
 (provide 'profiler)
index 19b8afe..d534a3f 100644 (file)
@@ -1,3 +1,9 @@
+2012-09-25  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * profiler.c: Rename sample_profiler_* to profiler_cpu_* and
+       memory_profiler_* to profiler_memory_*.  Move sigprof_handler before
+       its first use, inside the PROFILER_CPU_SUPPORT conditional.
+
 2012-09-24  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * profiler.c (evict_lower_half): Fix typo.
index 2fc93f8..8c0f99c 100644 (file)
@@ -5447,7 +5447,7 @@ See Info node `(elisp)Garbage Collection'.  */)
   FOR_EACH_BUFFER (nextb)
     compact_buffer (nextb);
 
-  if (memory_profiler_running)
+  if (profiler_memory_running)
     tot_before = total_bytes_of_live_objects ();
 
   start = current_emacs_time ();
@@ -5726,15 +5726,12 @@ See Info node `(elisp)Garbage Collection'.  */)
   gcs_done++;
 
   /* Collect profiling data.  */
-  if (memory_profiler_running)
+  if (profiler_memory_running)
     {
       size_t swept = 0;
-      if (memory_profiler_running)
-       {
-         size_t tot_after = total_bytes_of_live_objects ();
-         if (tot_before > tot_after)
-           swept = tot_before - tot_after;
-       }
+      size_t tot_after = total_bytes_of_live_objects ();
+      if (tot_before > tot_after)
+       swept = tot_before - tot_after;
       malloc_probe (swept);
     }
 
index f029a06..a0390fd 100644 (file)
@@ -3527,11 +3527,11 @@ void syms_of_dbusbind (void);
 
 
 /* Defined in profiler.c.  */
-extern bool memory_profiler_running;
+extern bool profiler_memory_running;
 extern void malloc_probe (size_t);
 #define MALLOC_PROBE(size)                     \
   do {                                         \
-    if (memory_profiler_running)               \
+    if (profiler_memory_running)               \
       malloc_probe (size);                     \
   } while (0)
 extern void syms_of_profiler (void);
index d22ab14..1c4fa0f 100644 (file)
@@ -25,17 +25,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 #include "lisp.h"
 
-/* True if sampling profiler is running.  */
-
-bool sample_profiler_running;
-
-/* True if memory profiler is running.  */
-
-bool memory_profiler_running;
-
-static void sigprof_handler (int, siginfo_t *, void *);
-
-\f
 /* Logs.  */
 
 typedef struct Lisp_Hash_Table log_t;
@@ -193,6 +182,9 @@ record_backtrace (log_t *log, size_t count)
 #if defined SIGPROF && defined HAVE_SETITIMER
 #define PROFILER_CPU_SUPPORT
 
+/* True if sampling profiler is running.  */
+static bool profiler_cpu_running;
+
 static Lisp_Object cpu_log;
 /* Separate counter for the time spent in the GC.  */
 static EMACS_INT cpu_gc_count;
@@ -201,23 +193,41 @@ static EMACS_INT cpu_gc_count;
 
 static int current_sample_interval;
 
-DEFUN ("sample-profiler-start", Fsample_profiler_start, Ssample_profiler_start,
+/* Signal handler for sample profiler.  */
+
+static void
+sigprof_handler (int signal, siginfo_t *info, void *ctx)
+{
+  eassert (HASH_TABLE_P (cpu_log));
+  if (backtrace_list && EQ (*backtrace_list->function, Qautomatic_gc))
+    /* Special case the time-count inside GC because the hash-table
+       code is not prepared to be used while the GC is running.
+       More specifically it uses ASIZE at many places where it does
+       not expect the ARRAY_MARK_FLAG to be set.  We could try and
+       harden the hash-table code, but it doesn't seem worth the
+       effort.  */
+    cpu_gc_count += current_sample_interval;
+  else
+    record_backtrace (XHASH_TABLE (cpu_log), current_sample_interval);
+}
+
+DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start,
        1, 1, 0,
-       doc: /* Start or restart sample profiler.  Sample profiler will
-take samples each SAMPLE-INTERVAL in millisecond.  See also
-`profiler-slot-heap-size' and `profiler-max-stack-depth'.  */)
+       doc: /* Start or restart the cpu profiler.
+The cpu profiler will take call-stack samples each SAMPLE-INTERVAL (expressed in milliseconds).
+See also `profiler-log-size' and `profiler-max-stack-depth'.  */)
   (Lisp_Object sample_interval)
 {
   struct sigaction sa;
   struct itimerval timer;
 
-  if (sample_profiler_running)
+  if (profiler_cpu_running)
     error ("Sample profiler is already running");
 
   if (NILP (cpu_log))
     {
       cpu_gc_count = 0;
-      cpu_log = make_log (profiler_slot_heap_size,
+      cpu_log = make_log (profiler_log_size,
                          profiler_max_stack_depth);
     }
 
@@ -233,48 +243,49 @@ take samples each SAMPLE-INTERVAL in millisecond.  See also
   timer.it_value = timer.it_interval;
   setitimer (ITIMER_PROF, &timer, 0);
 
-  sample_profiler_running = 1;
+  profiler_cpu_running = 1;
 
   return Qt;
 }
 
-DEFUN ("sample-profiler-stop", Fsample_profiler_stop, Ssample_profiler_stop,
+DEFUN ("profiler-cpu-stop", Fprofiler_cpu_stop, Sprofiler_cpu_stop,
        0, 0, 0,
-       doc: /* Stop sample profiler.  Profiler log will be kept.  */)
+       doc: /* Stop the cpu profiler.  The profiler log is not affected.  */)
   (void)
 {
-  if (!sample_profiler_running)
+  if (!profiler_cpu_running)
     error ("Sample profiler is not running");
-  sample_profiler_running = 0;
+  profiler_cpu_running = 0;
 
   setitimer (ITIMER_PROF, 0, 0);
 
   return Qt;
 }
 
-DEFUN ("sample-profiler-running-p",
-       Fsample_profiler_running_p, Ssample_profiler_running_p,
+DEFUN ("profiler-cpu-running-p",
+       Fprofiler_cpu_running_p, Sprofiler_cpu_running_p,
        0, 0, 0,
-       doc: /* Return t if sample profiler is running.  */)
+       doc: /* Return non-nil iff cpu profiler is running.  */)
   (void)
 {
-  return sample_profiler_running ? Qt : Qnil;
+  return profiler_cpu_running ? Qt : Qnil;
 }
 
-DEFUN ("sample-profiler-log",
-       Fsample_profiler_log, Ssample_profiler_log,
+DEFUN ("profiler-cpu-log", Fprofiler_cpu_log, Sprofiler_cpu_log,
        0, 0, 0,
-       doc: /* Return sample profiler log.  The data is a list of
-(sample nil TIMESTAMP SLOTS), where TIMESTAMP is a timestamp when the
-log is collected and SLOTS is a list of slots.  */)
+       doc: /* Return the current cpu profiler log.
+The log is a hash-table mapping backtraces to counters which represent
+the amount of time spent at those points.  Every backtrace is a vector
+of functions, where the last few elements may be nil.
+Before returning, a new log is allocated for future samples.  */)
   (void)
 {
   Lisp_Object result = cpu_log;
   /* Here we're making the log visible to Elisp , so it's not safe any
      more for our use afterwards since we can't rely on its special
      pre-allocated keys anymore.  So we have to allocate a new one.  */
-  cpu_log = (sample_profiler_running
-            ? make_log (profiler_slot_heap_size, profiler_max_stack_depth)
+  cpu_log = (profiler_cpu_running
+            ? make_log (profiler_log_size, profiler_max_stack_depth)
             : Qnil);
   Fputhash (Fmake_vector (make_number (1), Qautomatic_gc),
            make_number (cpu_gc_count),
@@ -282,66 +293,74 @@ log is collected and SLOTS is a list of slots.  */)
   cpu_gc_count = 0;
   return result;
 }
-#endif
+#endif /* not defined PROFILER_CPU_SUPPORT */
 \f
 /* Memory profiler.  */
 
+/* True if memory profiler is running.  */
+bool profiler_memory_running;
+
 static Lisp_Object memory_log;
 
-DEFUN ("memory-profiler-start", Fmemory_profiler_start, Smemory_profiler_start,
+DEFUN ("profiler-memory-start", Fprofiler_memory_start, Sprofiler_memory_start,
        0, 0, 0,
-       doc: /* Start/restart memory profiler.  See also
-`profiler-slot-heap-size' and `profiler-max-stack-depth'.  */)
+       doc: /* Start/restart the memory profiler.
+The memory profiler will take samples of the call-stack whenever a new
+allocation takes place.  Note that most small allocations only trigger
+the profiler occasionally.
+See also `profiler-log-size' and `profiler-max-stack-depth'.  */)
   (void)
 {
-  if (memory_profiler_running)
+  if (profiler_memory_running)
     error ("Memory profiler is already running");
 
   if (NILP (memory_log))
-    memory_log = make_log (profiler_slot_heap_size,
+    memory_log = make_log (profiler_log_size,
                           profiler_max_stack_depth);
 
-  memory_profiler_running = 1;
+  profiler_memory_running = 1;
 
   return Qt;
 }
 
-DEFUN ("memory-profiler-stop",
-       Fmemory_profiler_stop, Smemory_profiler_stop,
+DEFUN ("profiler-memory-stop",
+       Fprofiler_memory_stop, Sprofiler_memory_stop,
        0, 0, 0,
-       doc: /* Stop memory profiler.  Profiler log will be kept.  */)
+       doc: /* Stop the memory profiler.  The profiler log is not affected.  */)
   (void)
 {
-  if (!memory_profiler_running)
+  if (!profiler_memory_running)
     error ("Memory profiler is not running");
-  memory_profiler_running = 0;
+  profiler_memory_running = 0;
 
   return Qt;
 }
 
-DEFUN ("memory-profiler-running-p",
-       Fmemory_profiler_running_p, Smemory_profiler_running_p,
+DEFUN ("profiler-memory-running-p",
+       Fprofiler_memory_running_p, Sprofiler_memory_running_p,
        0, 0, 0,
-       doc: /* Return t if memory profiler is running.  */)
+       doc: /* Return non-nil if memory profiler is running.  */)
   (void)
 {
-  return memory_profiler_running ? Qt : Qnil;
+  return profiler_memory_running ? Qt : Qnil;
 }
 
-DEFUN ("memory-profiler-log",
-       Fmemory_profiler_log, Smemory_profiler_log,
+DEFUN ("profiler-memory-log",
+       Fprofiler_memory_log, Sprofiler_memory_log,
        0, 0, 0,
-       doc: /* Return memory profiler log.  The data is a list of
-(memory nil TIMESTAMP SLOTS), where TIMESTAMP is a timestamp when the
-log is collected and SLOTS is a list of slots.  */)
+       doc: /* Return the current memory profiler log.
+The log is a hash-table mapping backtraces to counters which represent
+the amount of memory allocated at those points.  Every backtrace is a vector
+of functions, where the last few elements may be nil.
+Before returning, a new log is allocated for future samples.  */)
   (void)
 {
   Lisp_Object result = memory_log;
   /* Here we're making the log visible to Elisp , so it's not safe any
      more for our use afterwards since we can't rely on its special
      pre-allocated keys anymore.  So we have to allocate a new one.  */
-  memory_log = (memory_profiler_running
-               ? make_log (profiler_slot_heap_size, profiler_max_stack_depth)
+  memory_log = (profiler_memory_running
+               ? make_log (profiler_log_size, profiler_max_stack_depth)
                : Qnil);
   return result;
 }
@@ -349,24 +368,6 @@ log is collected and SLOTS is a list of slots.  */)
 \f
 /* Signals and probes.  */
 
-/* Signal handler for sample profiler.  */
-
-static void
-sigprof_handler (int signal, siginfo_t *info, void *ctx)
-{
-  eassert (HASH_TABLE_P (cpu_log));
-  if (backtrace_list && EQ (*backtrace_list->function, Qautomatic_gc))
-    /* Special case the time-count inside GC because the hash-table
-       code is not prepared to be used while the GC is running.
-       More specifically it uses ASIZE at many places where it does
-       not expect the ARRAY_MARK_FLAG to be set.  We could try and
-       harden the hash-table code, but it doesn't seem worth the
-       effort.  */
-    cpu_gc_count += current_sample_interval;
-  else
-    record_backtrace (XHASH_TABLE (cpu_log), current_sample_interval);
-}
-
 /* Record that the current backtrace allocated SIZE bytes.  */
 void
 malloc_probe (size_t size)
@@ -379,26 +380,26 @@ void
 syms_of_profiler (void)
 {
   DEFVAR_INT ("profiler-max-stack-depth", profiler_max_stack_depth,
-             doc: /* FIXME */);
+             doc: /* Number of elements from the call-stack recorded in the log.  */);
   profiler_max_stack_depth = 16;
-  DEFVAR_INT ("profiler-slot-heap-size", profiler_slot_heap_size,
-             doc: /* FIXME */);
-  profiler_slot_heap_size = 10000;
+  DEFVAR_INT ("profiler-log-size", profiler_log_size,
+             doc: /* Number of distinct call-stacks that can be recorded in a profiler log.
+If the log gets full, some of the least-seen call-stacks will be evicted
+to make room for new entries.  */);
+  profiler_log_size = 10000;
 
-  /* FIXME: Rename things to start with "profiler-", to use "cpu" instead of
-     "sample", and to make them sound like they're internal or something.  */
 #ifdef PROFILER_CPU_SUPPORT
   cpu_log = Qnil;
   staticpro (&cpu_log);
-  defsubr (&Ssample_profiler_start);
-  defsubr (&Ssample_profiler_stop);
-  defsubr (&Ssample_profiler_running_p);
-  defsubr (&Ssample_profiler_log);
+  defsubr (&Sprofiler_cpu_start);
+  defsubr (&Sprofiler_cpu_stop);
+  defsubr (&Sprofiler_cpu_running_p);
+  defsubr (&Sprofiler_cpu_log);
 #endif
   memory_log = Qnil;
   staticpro (&memory_log);
-  defsubr (&Smemory_profiler_start);
-  defsubr (&Smemory_profiler_stop);
-  defsubr (&Smemory_profiler_running_p);
-  defsubr (&Smemory_profiler_log);
+  defsubr (&Sprofiler_memory_start);
+  defsubr (&Sprofiler_memory_stop);
+  defsubr (&Sprofiler_memory_running_p);
+  defsubr (&Sprofiler_memory_log);
 }