diff src/lrecord.h @ 5170:5ddbab03b0e6

various fixes to memory-usage stats -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-03-25 Ben Wing <ben@xemacs.org> * diagnose.el (show-memory-usage): * diagnose.el (show-object-memory-usage-stats): Further changes to correspond with changes in the C code; add an additional column in show-object-memory-usage-stats showing the ancillary Lisp overhead used with each type; shrink columns for windows in show-memory-usage to get it to fit in 79 chars. src/ChangeLog addition: 2010-03-25 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (struct): * alloc.c (finish_object_memory_usage_stats): * alloc.c (object_memory_usage_stats): * alloc.c (Fobject_memory_usage): * alloc.c (lisp_object_memory_usage_full): * alloc.c (compute_memusage_stats_length): * lrecord.h: * lrecord.h (struct lrecord_implementation): Add fields to the `lrecord_implementation' structure to list an offset into the array of extra statistics in a `struct generic_usage_stats' and a length, listing the first slice of ancillary Lisp-object memory. Compute automatically in compute_memusage_stats_length(). Use to add an entry `FOO-lisp-ancillary-storage' for object type FOO. Don't crash when an int or char is given to object-memory-usage, signal an error instead. Add functions lisp_object_memory_usage_full() and lisp_object_memory_usage() to compute the total memory usage of an object (sum of object, non-Lisp attached, and Lisp ancillary memory). * array.c: * array.c (gap_array_memory_usage): * array.h: Add function to return memory usage of a gap array. * buffer.c (struct buffer_stats): * buffer.c (compute_buffer_usage): * buffer.c (vars_of_buffer): * extents.c (compute_buffer_extent_usage): * marker.c: * marker.c (compute_buffer_marker_usage): * extents.h: * lisp.h: Remove `struct usage_stats' arg from compute_buffer_marker_usage() and compute_buffer_extent_usage() -- these are ancillary Lisp objects and don't get accumulated into `struct usage_stats'; change the value of `memusage_stats_list' so that `markers' and `extents' memory is in Lisp-ancillary, where it belongs. In compute_buffer_marker_usage(), use lisp_object_memory_usage() rather than lisp_object_storage_size(). * casetab.c: * casetab.c (case_table_memory_usage): * casetab.c (vars_of_casetab): * emacs.c (main_1): Add memory usage stats for case tables. * lisp.h: Add comment explaining the `struct generic_usage_stats' more, as well as the new fields in lrecord_implementation. * console-impl.h: * console-impl.h (struct console_methods): * scrollbar-gtk.c: * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): * scrollbar-msw.c: * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage): * scrollbar-x.c: * scrollbar-x.c (x_compute_scrollbar_instance_usage): * scrollbar.c: * scrollbar.c (struct scrollbar_instance_stats): * scrollbar.c (compute_all_scrollbar_instance_usage): * scrollbar.c (scrollbar_instance_memory_usage): * scrollbar.c (scrollbar_objects_create): * scrollbar.c (vars_of_scrollbar): * scrollbar.h: * symsinit.h: * window.c: * window.c (find_window_mirror_maybe): * window.c (struct window_mirror_stats): * window.c (compute_window_mirror_usage): * window.c (window_mirror_memory_usage): * window.c (compute_window_usage): * window.c (window_objects_create): * window.c (syms_of_window): * window.c (vars_of_window): Redo memory-usage associated with windows, window mirrors, and scrollbar instances. Should fix crash in find_window_mirror, among other things. Properly assign memo ry to object memory, non-Lisp extra memory, and Lisp ancillary memory. For example, redisplay structures are non-Lisp memory hanging off a window mirror, not a window; make it an ancillary Lisp-object field. Window mirrors and scrollbar instances have their own statistics, among other things.
author Ben Wing <ben@xemacs.org>
date Thu, 25 Mar 2010 06:07:25 -0500
parents 6c6d78781d59
children 97eb4942aec8 14fda1dbdb26
line wrap: on
line diff
--- a/src/lrecord.h	Wed Mar 24 01:22:51 2010 -0500
+++ b/src/lrecord.h	Thu Mar 25 06:07:25 2010 -0500
@@ -514,8 +514,8 @@
 
   /**********************************************************************/
   /* Remaining stuff is not assignable statically using
-     DEFINE_*_LISP_OBJECT, but must be assigned with OBJECT_HAS_METHOD
-     or the like. */
+     DEFINE_*_LISP_OBJECT, but must be assigned with OBJECT_HAS_METHOD,
+     OBJECT_HAS_PROPERTY or the like. */
 
   /* These functions allow any object type to have builtin property
      lists that can be manipulated from the lisp level with
@@ -542,34 +542,73 @@
 
 #ifdef MEMORY_USAGE_STATS
   /* Return memory-usage information about the object in question, stored
-     into STATS. */
-  void (*memory_usage) (Lisp_Object obj, struct generic_usage_stats *stats);
+     into STATS.
 
-  /* Number of additional type-specific statistics related to memory usage.
-     Automatically calculated (see compute_memusage_stats_length()) based
-     on the value placed in `memusage_stats_list'. */
-  Elemcount num_extra_memusage_stats;
+     Two types of information are stored: storage (including overhead) for
+     ancillary non-Lisp structures attached to the object, and storage
+     (including overhead) for ancillary Lisp objects attached to the
+     object.  The third type of memory-usage information (storage for the
+     object itself) is not noted here, because it's computed automatically
+     by the calling function.  Also, the computed storage for ancillary
+     Lisp objects is the sum of all three source of memory associated with
+     the Lisp object: the object itself, ancillary non-Lisp structures and
+     ancillary Lisp objects.  Note also that the `struct usage_stats u' at
+     the beginning of the STATS structure is for ancillary non-Lisp usage
+     *ONLY*; do not store any memory into it related to ancillary Lisp
+     objects.
 
-  /* Number of additional type-specific statistics related to
-     non-Lisp-Object memory usage for this object.  Automatically
-     calculated (see compute_memusage_stats_length()) based on the value
-     placed in `memusage_stats_list'. */
-  Elemcount num_extra_nonlisp_memusage_stats;
+     Note that it may be subjective which Lisp objects are considered
+     "attached" to the object.  Some guidelines:
+
+     -- Lisp objects which are "internal" to the main object and not
+        accessible except through the main object should be included
+     -- Objects linked by a weak reference should *NOT* be included
+  */
+  void (*memory_usage) (Lisp_Object obj, struct generic_usage_stats *stats);
 
   /* List of tags to be given to the extra statistics, one per statistic.
      Qnil or Qt can be present to separate off different slices.  Qnil
-     separates different slices within the same type of statistics.
-     Qt separates slices corresponding to different types of statistics.
+     separates different slices within the same group of statistics.
+     These represent different ways of partitioning the same memory space.
+     Qt separates different groups; these represent different spaces of
+     memory.
+
      If Qt is not present, all slices describe extra non-Lisp-Object memory
-     associated with a Lisp object.  If Qt is present, slices after Qt
-     describe non-Lisp-Object memory and slices before Qt describe
-     Lisp-Object memory logically associated with the object.  For example,
-     if the object is a table, then Lisp-Object memory might be the entries
-     in the table.  This info is only advisory since it will duplicate
-     memory described elsewhere and since it may not be possible to be
-     completely accurate if the same object occurs multiple times in the
-     table. */
+     associated with a Lisp object.  If Qt is present, slices before Qt
+     describe non-Lisp-Object memory, as before, and slices after Qt
+     describe ancillary Lisp-Object memory logically associated with the
+     object.  For example, if the object is a table, then ancillary
+     Lisp-Object memory might be the entries in the table.  This info is
+     only advisory since it will duplicate memory described elsewhere and
+     since it may not be possible to be completely accurate, e.g. it may
+     not be clear what to count in "ancillary objects", and the value may
+     be too high if the same object occurs multiple times in the table. */
   Lisp_Object memusage_stats_list;
+
+  /* --------------------------------------------------------------------- */
+
+  /* The following are automatically computed based on the value in
+     `memusage_stats_list' (see compute_memusage_stats_length()). */
+
+  /* Total number of additional type-specific statistics related to memory
+     usage. */
+  Elemcount num_extra_memusage_stats;
+
+  /* Number of additional type-specific statistics belonging to the first
+     slice of the group describing non-Lisp-Object memory usage for this
+     object.  These stats occur starting at offset 0. */
+  Elemcount num_extra_nonlisp_memusage_stats;
+
+  /* The offset into the extra statistics at which the Lisp-Object
+     memory-usage statistics begin. */
+  Elemcount offset_lisp_ancillary_memusage_stats;
+
+  /* Number of additional type-specific statistics belonging to the first
+     slice of the group describing Lisp-Object memory usage for this
+     object.  These stats occur starting at offset
+     `offset_lisp_ancillary_memusage_stats'. */
+  Elemcount num_extra_lisp_ancillary_memusage_stats;
+
 #endif /* MEMORY_USAGE_STATS */
 };
 
@@ -2040,6 +2079,12 @@
 MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj);
 Bytecount lisp_object_storage_size (Lisp_Object obj,
 				    struct usage_stats *ustats);
+Bytecount lisp_object_memory_usage_full (Lisp_Object object,
+					 Bytecount *storage_size,
+					 Bytecount *extra_nonlisp_storage,
+					 Bytecount *extra_lisp_storage,
+					 struct generic_usage_stats *stats);
+Bytecount lisp_object_memory_usage (Lisp_Object object);
 void free_normal_lisp_object (Lisp_Object obj);