carbon2-commit: various fixes to memory-usage stats
Ben Wing
ben at xemacs.org
Sat Apr 17 07:07:42 EDT 2010
changeset: 5222:5ddbab03b0e6
user: Ben Wing <ben at xemacs.org>
date: Thu Mar 25 06:07:25 2010 -0500
files: lisp/ChangeLog lisp/diagnose.el src/ChangeLog src/alloc.c src/array.c src/array.h src/buffer.c src/casetab.c src/console-impl.h src/emacs.c src/extents.c src/extents.h src/lisp.h src/lrecord.h src/marker.c src/scrollbar-gtk.c src/scrollbar-msw.c src/scrollbar-x.c src/scrollbar.c src/scrollbar.h src/symsinit.h src/window.c
description:
various fixes to memory-usage stats
-------------------- ChangeLog entries follow: --------------------
lisp/ChangeLog addition:
2010-03-25 Ben Wing <ben at 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 at 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.
diff -r 6c6d78781d59 -r 5ddbab03b0e6 lisp/ChangeLog
--- a/lisp/ChangeLog Wed Mar 24 01:22:51 2010 -0500
+++ b/lisp/ChangeLog Thu Mar 25 06:07:25 2010 -0500
@@ -1,3 +1,12 @@
+2010-03-25 Ben Wing <ben at 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.
+
2010-03-20 Ben Wing <ben at xemacs.org>
* diagnose.el (show-memory-usage):
diff -r 6c6d78781d59 -r 5ddbab03b0e6 lisp/diagnose.el
--- a/lisp/diagnose.el Wed Mar 24 01:22:51 2010 -0500
+++ b/lisp/diagnose.el Thu Mar 25 06:07:25 2010 -0500
@@ -35,11 +35,12 @@
"Show statistics about memory usage of various sorts in XEmacs."
(interactive)
(garbage-collect)
- (flet ((show-foo-stats (objtypename cleanfun objlist)
+ (flet ((show-foo-stats (objtypename statname-plist cleanfun objlist
+ &optional objnamelen)
(let* ((hash (make-hash-table))
(first t)
- types fmt
- (objnamelen 25)
+ types origtypes fmt
+ (objnamelen (or objnamelen 25))
(linelen objnamelen)
(totaltotal 0))
(loop for obj in objlist do
@@ -54,19 +55,22 @@
;; the memory grouped by type
(while (and stats (pop stats)))
- (loop for (type . num) in stats while type do
+ (loop for (type . num) in (remq t stats) while type do
+ (if first (push type origtypes))
+ (setq type (getf statname-plist type type))
(puthash type (+ num (or (gethash type hash) 0)) hash)
(incf total num)
(if first (push type types)))
(incf totaltotal total)
(when first
(setq types (nreverse types))
+ (setq origtypes (nreverse origtypes))
(setq fmt (concat
(format "%%-%ds" objnamelen)
(mapconcat
#'(lambda (type)
(let ((fieldlen
- (max 8 (+ 2 (length
+ (max 7 (+ 2 (length
(symbol-name type))))))
(incf linelen fieldlen)
(format "%%%ds" fieldlen)))
@@ -83,7 +87,7 @@
(1- objnamelen)))
(nconc (mapcar #'(lambda (type)
(cdr (assq type stats)))
- types)
+ origtypes)
(list total)))))
(setq first nil)))
(princ "\n")
@@ -103,7 +107,7 @@
(when-fboundp 'charset-list
(setq begin (point))
(incf grandtotal
- (show-foo-stats 'charset 'charset-name
+ (show-foo-stats 'charset nil 'charset-name
(mapcar 'get-charset (charset-list))))
(when-fboundp 'sort-numeric-fields
(sort-numeric-fields -1
@@ -117,7 +121,7 @@
(princ "\n"))
(setq begin (point))
(incf grandtotal
- (show-foo-stats 'buffer 'buffer-name (buffer-list)))
+ (show-foo-stats 'buffer nil 'buffer-name (buffer-list)))
(when-fboundp 'sort-numeric-fields
(sort-numeric-fields -1
(save-excursion
@@ -130,11 +134,19 @@
(princ "\n")
(setq begin (point))
(incf grandtotal
- (show-foo-stats 'window #'(lambda (x)
- (buffer-name (window-buffer x)))
+ (show-foo-stats 'window
+ '(line-start-cache line-st.
+ face-cache face
+ glyph-cache glyph
+ redisplay-structs redisplay
+ scrollbar-instances scrollbar
+ window-mirror mirror)
+ #'(lambda (x)
+ (buffer-name (window-buffer x)))
(mapcan #'(lambda (fr)
(window-list fr t))
- (frame-list))))
+ (frame-list))
+ 16))
(when-fboundp #'sort-numeric-fields
(sort-numeric-fields -1
(save-excursion
@@ -152,9 +164,14 @@
(princ (make-string 40 ?-))
(princ "\n")
(map-plist #'(lambda (stat num)
- (when (string-match
- "\\(.*\\)-storage$"
- (symbol-name stat))
+ (when (and
+ (not
+ (string-match
+ "\\(.*\\)-ancillary-storage$"
+ (symbol-name stat)))
+ (string-match
+ "\\(.*\\)-storage$"
+ (symbol-name stat)))
(incf total num)
(princ (format fmt
(match-string 1 (symbol-name stat))
@@ -184,12 +201,14 @@
(garbage-collect)
(let ((buffer "*object memory usage statistics*")
(plist (object-memory-usage-stats))
- (fmt "%-30s%10s%10s%10s%18s\n")
+ (fmt "%-28s%10s%10s%10s%10s%10s\n")
(grandtotal 0)
begin)
(flet ((show-stats (match-string)
- (princ (format fmt "object" "count" "storage" "overhead"
- "non-Lisp storage"))
+ (princ (format "%28s%10s%40s\n" "" ""
+ "--------------storage---------------"))
+ (princ (format fmt "object" "count" "object" "overhead"
+ "non-Lisp" "ancillary"))
(princ (make-string 78 ?-))
(princ "\n")
(let ((total-use 0)
@@ -202,9 +221,13 @@
(let ((symmatch
(and (string-match match-string (symbol-name stat))
(match-string 1 (symbol-name stat)))))
- (when (and symmatch (or (< (length symmatch) 9)
- (not (equal (substring symmatch -9)
- "-non-lisp"))))
+ (when (and symmatch
+ (or (< (length symmatch) 9)
+ (not (equal (substring symmatch -9)
+ "-non-lisp")))
+ (or (< (length symmatch) 15)
+ (not (equal (substring symmatch -15)
+ "-lisp-ancillary"))))
(let* ((storage-use num)
(storage-use-overhead
(or (plist-get
@@ -226,6 +249,12 @@
plist
(intern (concat symmatch
"-non-lisp-storage")))
+ 0))
+ (lisp-ancillary-storage
+ (or (plist-get
+ plist
+ (intern (concat symmatch
+ "-lisp-ancillary-storage")))
0))
(storage-count
(or (loop for str in '("s-used" "es-used" "-used")
@@ -251,19 +280,20 @@
(or storage-count "unknown")
storage-use
storage-use-overhead
- non-lisp-storage)))))))
+ non-lisp-storage
+ lisp-ancillary-storage)))))))
plist)
(princ "\n")
(princ (format fmt "total"
total-count total-use total-use-overhead
- total-non-lisp-use))
+ total-non-lisp-use ""))
(incf grandtotal total-use-with-overhead)
(incf grandtotal total-non-lisp-use)
(when-fboundp #'sort-numeric-fields
- (sort-numeric-fields -3
+ (sort-numeric-fields -4
(save-excursion
(goto-char begin)
- (forward-line 3)
+ (forward-line 4)
(point))
(save-excursion
(forward-line -2)
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/ChangeLog
--- a/src/ChangeLog Wed Mar 24 01:22:51 2010 -0500
+++ b/src/ChangeLog Thu Mar 25 06:07:25 2010 -0500
@@ -1,3 +1,95 @@
+2010-03-25 Ben Wing <ben at 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.
+
2010-03-24 Ben Wing <ben at xemacs.org>
* array.h:
@@ -6,7 +98,7 @@
* dumper.c (pdump_store_new_pointer_offsets):
* dumper.c (pdump_reloc_one_mc):
* elhash.c:
- * gc.c (lispdesc_one_description_line_size):
+ * gc.c (lispdesc_one_description_line_size):
* gc.c (kkcc_marking):
* lrecord.h:
* lrecord.h (IF_NEW_GC):
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/alloc.c
--- a/src/alloc.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/alloc.c Thu Mar 25 06:07:25 2010 -0500
@@ -177,6 +177,7 @@
Bytecount bytes_on_free_list_overhead;
#ifdef MEMORY_USAGE_STATS
Bytecount nonlisp_bytes_in_use;
+ Bytecount lisp_ancillary_bytes_in_use;
struct generic_usage_stats stats;
#endif
} lrecord_stats [countof (lrecord_implementations_table)];
@@ -3888,6 +3889,14 @@
lrecord_stats[i].nonlisp_bytes_in_use +=
lrecord_stats[i].stats.othervals[j];
}
+ if (imp && imp->num_extra_lisp_ancillary_memusage_stats)
+ {
+ int j;
+ for (j = 0; j < imp->num_extra_lisp_ancillary_memusage_stats; j++)
+ lrecord_stats[i].lisp_ancillary_bytes_in_use +=
+ lrecord_stats[i].stats.othervals
+ [j + imp->offset_lisp_ancillary_memusage_stats];
+ }
}
#endif /* defined (MEMORY_USAGE_STATS) && !defined (NEW_GC) */
}
@@ -4040,6 +4049,14 @@
pl = gc_plist_hack (buf, lrecord_stats[i].nonlisp_bytes_in_use,
pl);
tgu_val += lrecord_stats[i].nonlisp_bytes_in_use;
+ }
+ if (lrecord_stats[i].lisp_ancillary_bytes_in_use)
+ {
+ sprintf (buf, "%s-lisp-ancillary-storage", name);
+ pl = gc_plist_hack (buf, lrecord_stats[i].
+ lisp_ancillary_bytes_in_use,
+ pl);
+ tgu_val += lrecord_stats[i].lisp_ancillary_bytes_in_use;
}
#endif /* MEMORY_USAGE_STATS */
pluralize_and_append (buf, name, "-freed");
@@ -4175,7 +4192,13 @@
struct usage_stats object_stats;
int i;
Lisp_Object val = Qnil;
- Lisp_Object stats_list = OBJECT_PROPERTY (object, memusage_stats_list);
+ Lisp_Object stats_list;
+
+ if (INTP (object) || CHARP (object))
+ invalid_argument ("No memory associated with immediate objects (int or char)",
+ object);
+
+ stats_list = OBJECT_PROPERTY (object, memusage_stats_list);
xzero (object_stats);
lisp_object_storage_size (object, &object_stats);
@@ -4223,6 +4246,80 @@
return Fnreverse (val);
}
+/* Compute total memory usage associated with an object, including
+
+ (a) Storage (including overhead) allocated to the object itself
+ (b) Storage (including overhead) for ancillary non-Lisp structures attached
+ to the object
+ (c) Storage (including overhead) for ancillary Lisp objects attached
+ to the object
+
+ Store the three types of memory into the return values provided they
+ aren't NULL, and return a sum of the three values. Also store the
+ structure of individual statistics into STATS if non-zero.
+
+ Note that the value for type (c) is the sum of all three types of
+ memory associated with the ancillary Lisp objects.
+*/
+
+Bytecount
+lisp_object_memory_usage_full (Lisp_Object object, Bytecount *storage_size,
+ Bytecount *extra_nonlisp_storage,
+ Bytecount *extra_lisp_ancillary_storage,
+ struct generic_usage_stats *stats)
+{
+ Bytecount total;
+ struct lrecord_implementation *imp = XRECORD_LHEADER_IMPLEMENTATION (object);
+
+ total = lisp_object_storage_size (object, NULL);
+ if (storage_size)
+ *storage_size = total;
+
+ if (HAS_OBJECT_METH_P (object, memory_usage))
+ {
+ int i;
+ struct generic_usage_stats gustats;
+ Bytecount sum;
+
+ xzero (gustats);
+ OBJECT_METH (object, memory_usage, (object, &gustats));
+
+ if (stats)
+ *stats = gustats;
+
+ sum = 0;
+ for (i = 0; i < imp->num_extra_nonlisp_memusage_stats; i++)
+ sum += gustats.othervals[i];
+ total += sum;
+ if (extra_nonlisp_storage)
+ *extra_nonlisp_storage = sum;
+
+ sum = 0;
+ for (i = 0; i < imp->num_extra_lisp_ancillary_memusage_stats; i++)
+ sum += gustats.othervals[imp->offset_lisp_ancillary_memusage_stats +
+ i];
+ total += sum;
+ if (extra_lisp_ancillary_storage)
+ *extra_lisp_ancillary_storage = sum;
+ }
+ else
+ {
+ if (extra_nonlisp_storage)
+ *extra_nonlisp_storage = 0;
+ if (extra_lisp_ancillary_storage)
+ *extra_lisp_ancillary_storage = 0;
+ }
+
+ return total;
+}
+
+
+Bytecount
+lisp_object_memory_usage (Lisp_Object object)
+{
+ return lisp_object_memory_usage_full (object, NULL, NULL, NULL, NULL);
+}
+
#endif /* MEMORY_USAGE_STATS */
#ifdef ALLOC_TYPE_STATS
@@ -4258,10 +4355,6 @@
for (i = 0; i < countof (lrecord_implementations_table); i++)
{
- int len = 0;
- int nonlisp_len = 0;
- int seen_break = 0;
-
struct lrecord_implementation *imp = lrecord_implementations_table[i];
if (!imp)
@@ -4272,21 +4365,44 @@
if (EQ (imp->memusage_stats_list, Qnull_pointer))
imp->memusage_stats_list = Qnil;
{
+ Elemcount len = 0;
+ Elemcount nonlisp_len = 0;
+ Elemcount lisp_len = 0;
+ Elemcount lisp_offset = 0;
+ int group_num = 0;
+ int slice_num = 0;
+
LIST_LOOP_2 (item, imp->memusage_stats_list)
{
- if (!NILP (item) && !EQ (item, Qt))
+ if (EQ (item, Qt))
{
- len++;
- if (!seen_break)
- nonlisp_len++;
+ group_num++;
+ if (group_num == 1)
+ lisp_offset = len;
+ slice_num = 0;
+ }
+ else if (EQ (item, Qnil))
+ {
+ slice_num++;
}
else
- seen_break++;
+ {
+ if (slice_num == 0)
+ {
+ if (group_num == 0)
+ nonlisp_len++;
+ else if (group_num == 1)
+ lisp_len++;
+ }
+ len++;
+ }
}
- }
-
- imp->num_extra_memusage_stats = len;
- imp->num_extra_nonlisp_memusage_stats = nonlisp_len;
+
+ imp->num_extra_memusage_stats = len;
+ imp->num_extra_nonlisp_memusage_stats = nonlisp_len;
+ imp->num_extra_lisp_ancillary_memusage_stats = lisp_len;
+ imp->offset_lisp_ancillary_memusage_stats = lisp_offset;
+ }
}
}
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/array.c
--- a/src/array.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/array.c Thu Mar 25 06:07:25 2010 -0500
@@ -940,6 +940,59 @@
}
#endif /* not NEW_GC */
+#ifdef MEMORY_USAGE_STATS
+
+/* Return memory usage for gap array GA. The returned value is the total
+ amount of bytes actually being used for the gap array, including all
+ overhead. The extra amount of space in the gap array that is used
+ for the gap is counted in GAP_OVERHEAD, not in WAS_REQUESTED.
+ If NEW_GC, space for gap-array markers is returned through MARKER_ANCILLARY;
+ otherwise it's added into the gap array usage. */
+
+Bytecount
+gap_array_memory_usage (Gap_Array *ga, struct usage_stats *stats,
+ Bytecount *marker_ancillary)
+{
+ Bytecount total = 0;
+
+ /* We have to be a bit tricky here because not all of the
+ memory that malloc() will claim as "requested" was actually
+ requested -- some of it makes up the gap. */
+
+ Bytecount size = gap_array_byte_size (ga);
+ Bytecount gap_size = ga->gapsize * ga->elsize;
+ Bytecount malloc_used = malloced_storage_size (ga, size, 0);
+ total += malloc_used;
+ stats->was_requested += size - gap_size;
+ stats->gap_overhead += gap_size;
+ stats->malloc_overhead += malloc_used - size;
+
+#ifdef NEW_GC
+ {
+ Bytecount marker_usage = 0;
+ Gap_Array_Marker *p;
+
+ for (p = ga->markers; p; p = p->next)
+ marker_usage += lisp_object_memory_usage (wrap_gap_array_marker (p));
+ if (marker_ancillary)
+ *marker_ancillary = marker_usage;
+ }
+#else
+ {
+ Gap_Array_Marker *p;
+
+ for (p = ga->markers; p; p = p->next)
+ total += malloced_storage_size (p, sizeof (p), stats);
+ if (marker_ancillary)
+ *marker_ancillary = 0;
+ }
+#endif /* (not) NEW_GC */
+
+ return total;
+}
+
+#endif /* MEMORY_USAGE_STATS */
+
/*****************************************************************************/
/* Initialization */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/array.h
--- a/src/array.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/array.h Thu Mar 25 06:07:25 2010 -0500
@@ -763,5 +763,7 @@
Gap_Array *make_gap_array (Elemcount elsize, int USED_IF_NEW_GC (do_lisp));
Gap_Array *gap_array_clone (Gap_Array *ga);
void free_gap_array (Gap_Array *ga);
+Bytecount gap_array_memory_usage (Gap_Array *ga, struct usage_stats *stats,
+ Bytecount *marker_ancillary);
#endif /* INCLUDED_array_h_ */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/buffer.c
--- a/src/buffer.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/buffer.c Thu Mar 25 06:07:25 2010 -0500
@@ -1754,6 +1754,7 @@
{
struct usage_stats u;
Bytecount text;
+ /* Ancillary Lisp */
Bytecount markers;
Bytecount extents;
};
@@ -1787,8 +1788,8 @@
struct usage_stats *ustats)
{
stats->text += compute_buffer_text_usage (b, ustats);
- stats->markers += compute_buffer_marker_usage (b, ustats);
- stats->extents += compute_buffer_extent_usage (b, ustats);
+ stats->markers += compute_buffer_marker_usage (b);
+ stats->extents += compute_buffer_extent_usage (b);
}
static void
@@ -1976,7 +1977,7 @@
/* This function can GC */
#ifdef MEMORY_USAGE_STATS
OBJECT_HAS_PROPERTY
- (buffer, memusage_stats_list, list3 (Qtext, Qmarkers, Qextents));
+ (buffer, memusage_stats_list, list4 (Qtext, Qt, Qmarkers, Qextents));
#endif /* MEMORY_USAGE_STATS */
staticpro (&QSFundamental);
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/casetab.c
--- a/src/casetab.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/casetab.c Thu Mar 25 06:07:25 2010 -0500
@@ -508,6 +508,38 @@
}
+#ifdef MEMORY_USAGE_STATS
+
+struct case_table_stats
+{
+ struct usage_stats u;
+ /* Ancillary Lisp */
+ Bytecount downcase, upcase, case_canon, case_eqv;
+};
+
+static void
+case_table_memory_usage (Lisp_Object casetab,
+ struct generic_usage_stats *gustats)
+{
+ struct case_table_stats *stats = (struct case_table_stats *) gustats;
+
+ stats->downcase = lisp_object_memory_usage (XCASE_TABLE_DOWNCASE (casetab));
+ stats->upcase = lisp_object_memory_usage (XCASE_TABLE_UPCASE (casetab));
+ stats->case_canon = lisp_object_memory_usage (XCASE_TABLE_CANON (casetab));
+ stats->case_eqv = lisp_object_memory_usage (XCASE_TABLE_EQV (casetab));
+}
+
+#endif /* MEMORY_USAGE_STATS */
+
+
+void
+casetab_objects_create (void)
+{
+#ifdef MEMORY_USAGE_STATS
+ OBJECT_HAS_METHOD (case_table, memory_usage);
+#endif
+}
+
void
syms_of_casetab (void)
{
@@ -527,6 +559,19 @@
DEFSUBR (Fcopy_case_table);
DEFSUBR (Fset_case_table);
DEFSUBR (Fset_standard_case_table);
+}
+
+void
+vars_of_casetab (void)
+{
+#ifdef MEMORY_USAGE_STATS
+ OBJECT_HAS_PROPERTY (case_table, memusage_stats_list,
+ list5 (Qt,
+ intern ("downcase"),
+ intern ("upcase"),
+ intern ("case-canon"),
+ intern ("case-eqv")));
+#endif /* MEMORY_USAGE_STATS */
}
void
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/console-impl.h
--- a/src/console-impl.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/console-impl.h Thu Mar 25 06:07:25 2010 -0500
@@ -1,5 +1,5 @@
/* Define console object for XEmacs.
- Copyright (C) 1996, 2002, 2003, 2005 Ben Wing
+ Copyright (C) 1996, 2002, 2003, 2005, 2010 Ben Wing
This file is part of XEmacs.
@@ -290,9 +290,10 @@
scrollbar_instance *);
void (*scrollbar_pointer_changed_in_window_method) (struct window *w);
#ifdef MEMORY_USAGE_STATS
- int (*compute_scrollbar_instance_usage_method) (struct device *,
- struct scrollbar_instance *,
- struct usage_stats *);
+ Bytecount (*compute_scrollbar_instance_usage_method)
+ (struct device *,
+ struct scrollbar_instance *,
+ struct usage_stats *);
#endif
/* Paint the window's deadbox, a rectangle between window
borders and two short edges of both scrollbars. */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/emacs.c
--- a/src/emacs.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/emacs.c Thu Mar 25 06:07:25 2010 -0500
@@ -1763,6 +1763,7 @@
)
{
buffer_objects_create ();
+ casetab_objects_create ();
extent_objects_create ();
face_objects_create ();
frame_objects_create ();
@@ -1771,6 +1772,9 @@
lstream_objects_create ();
#ifdef MULE
mule_charset_objects_create ();
+#endif
+#ifdef HAVE_SCROLLBARS
+ scrollbar_objects_create ();
#endif
#ifdef HAVE_GTK
ui_gtk_objects_create ();
@@ -2094,6 +2098,7 @@
vars_of_buffer ();
vars_of_bytecode ();
vars_of_callint ();
+ vars_of_casetab ();
vars_of_chartab ();
vars_of_cmdloop ();
vars_of_cmds ();
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/extents.c
--- a/src/extents.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/extents.c Thu Mar 25 06:07:25 2010 -0500
@@ -7003,9 +7003,8 @@
#ifdef MEMORY_USAGE_STATS
-int
-compute_buffer_extent_usage (struct buffer *UNUSED (b),
- struct usage_stats *UNUSED (ustats))
+Bytecount
+compute_buffer_extent_usage (struct buffer *UNUSED (b))
{
/* #### not yet written */
return 0;
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/extents.h
--- a/src/extents.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/extents.h Thu Mar 25 06:07:25 2010 -0500
@@ -218,8 +218,7 @@
#endif
#ifdef MEMORY_USAGE_STATS
-int compute_buffer_extent_usage (struct buffer *b,
- struct usage_stats *ustats);
+Bytecount compute_buffer_extent_usage (struct buffer *b);
#endif
#endif /* INCLUDED_extents_h_ */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/lisp.h
--- a/src/lisp.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/lisp.h Thu Mar 25 06:07:25 2010 -0500
@@ -1619,6 +1619,18 @@
Bytecount gap_overhead;
};
+/* Generic version of usage stats structure including extra non-Lisp and
+ Lisp storage associated with the object, but not including the memory
+ used to hold the object itself. Up to 32 statistics are allowed,
+ in addition to the statistics in `U', which store another slice onto the
+ ancillary non-Lisp storage.
+
+ Normally, each object creates its own version of this structure, e.g.
+ `struct window_stats', which parallels the structure in beginning with
+ a `struct usage_stats' and followed by Bytecount fields, so that a
+ pointer to that structure can be cast to a pointer of this structure
+ and sensible results gotten. */
+
struct generic_usage_stats
{
struct usage_stats u;
@@ -5334,7 +5346,7 @@
Lisp_Object noseeum_copy_marker (Lisp_Object, Lisp_Object);
Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object);
#ifdef MEMORY_USAGE_STATS
-Bytecount compute_buffer_marker_usage (struct buffer *, struct usage_stats *);
+Bytecount compute_buffer_marker_usage (struct buffer *b);
#endif
void init_buffer_markers (struct buffer *b);
void uninit_buffer_markers (struct buffer *b);
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/lrecord.h
--- 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. */
+ into 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.
+
+ 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);
-
- /* 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;
-
- /* 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;
/* 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);
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/marker.c
--- a/src/marker.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/marker.c Thu Mar 25 06:07:25 2010 -0500
@@ -493,13 +493,13 @@
#ifdef MEMORY_USAGE_STATS
Bytecount
-compute_buffer_marker_usage (struct buffer *b, struct usage_stats *ustats)
+compute_buffer_marker_usage (struct buffer *b)
{
Lisp_Marker *m;
Bytecount total = 0;
for (m = BUF_MARKERS (b); m; m = m->next)
- total += lisp_object_storage_size (wrap_marker (m), ustats);
+ total += lisp_object_memory_usage (wrap_marker (m));
return total;
}
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/scrollbar-gtk.c
--- a/src/scrollbar-gtk.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/scrollbar-gtk.c Thu Mar 25 06:07:25 2010 -0500
@@ -476,23 +476,15 @@
}
#ifdef MEMORY_USAGE_STATS
-static int
+static Bytecount
gtk_compute_scrollbar_instance_usage (struct device *UNUSED (d),
struct scrollbar_instance *inst,
struct usage_stats *ustats)
{
- int total = 0;
+ struct gtk_scrollbar_data *data =
+ (struct gtk_scrollbar_data *) inst->scrollbar_data;
- while (inst)
- {
- struct gtk_scrollbar_data *data =
- (struct gtk_scrollbar_data *) inst->scrollbar_data;
-
- total += malloced_storage_size (data, sizeof (*data), ustats);
- inst = inst->next;
- }
-
- return total;
+ return malloced_storage_size (data, sizeof (*data), ustats);
}
#endif /* MEMORY_USAGE_STATS */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/scrollbar-msw.c
--- a/src/scrollbar-msw.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/scrollbar-msw.c Thu Mar 25 06:07:25 2010 -0500
@@ -424,23 +424,15 @@
#ifdef MEMORY_USAGE_STATS
-static int
+static Bytecount
mswindows_compute_scrollbar_instance_usage (struct device *UNUSED (d),
struct scrollbar_instance *inst,
struct usage_stats *ustats)
{
- int total = 0;
+ struct mswindows_scrollbar_data *data =
+ (struct mswindows_scrollbar_data *) inst->scrollbar_data;
- while (inst)
- {
- struct mswindows_scrollbar_data *data =
- (struct mswindows_scrollbar_data *) inst->scrollbar_data;
-
- total += malloced_storage_size (data, sizeof (*data), ustats);
- inst = inst->next;
- }
-
- return total;
+ return malloced_storage_size (data, sizeof (*data), ustats);
}
#endif /* MEMORY_USAGE_STATS */
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/scrollbar-x.c
--- a/src/scrollbar-x.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/scrollbar-x.c Thu Mar 25 06:07:25 2010 -0500
@@ -698,23 +698,18 @@
#ifdef MEMORY_USAGE_STATS
-static int
+static Bytecount
x_compute_scrollbar_instance_usage (struct device *UNUSED (d),
struct scrollbar_instance *inst,
struct usage_stats *ustats)
{
- int total = 0;
+ Bytecount total = 0;
+ struct x_scrollbar_data *data =
+ (struct x_scrollbar_data *) inst->scrollbar_data;
- while (inst)
- {
- struct x_scrollbar_data *data =
- (struct x_scrollbar_data *) inst->scrollbar_data;
-
- total += malloced_storage_size (data, sizeof (*data), ustats);
- total += malloced_storage_size (data->name, 1 + strlen (data->name),
- ustats);
- inst = inst->next;
- }
+ total += malloced_storage_size (data, sizeof (*data), ustats);
+ total += malloced_storage_size (data->name, 1 + strlen (data->name),
+ ustats);
return total;
}
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/scrollbar.c
--- a/src/scrollbar.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/scrollbar.c Thu Mar 25 06:07:25 2010 -0500
@@ -257,24 +257,41 @@
#ifdef MEMORY_USAGE_STATS
-int
-compute_scrollbar_instance_usage (struct device *d,
- struct scrollbar_instance *inst,
- struct usage_stats *ustats)
+struct scrollbar_instance_stats
{
- int total = 0;
+ struct usage_stats u;
+ Bytecount device_data;
+};
- if (HAS_DEVMETH_P(d, compute_scrollbar_instance_usage))
- total += DEVMETH (d, compute_scrollbar_instance_usage, (d, inst, ustats));
+Bytecount
+compute_all_scrollbar_instance_usage (struct scrollbar_instance *inst)
+{
+ Bytecount total = 0;
while (inst)
{
- total += lisp_object_storage_size (wrap_scrollbar_instance (inst),
- ustats);
+ total += lisp_object_memory_usage (wrap_scrollbar_instance (inst));
inst = inst->next;
}
return total;
+}
+
+static void
+scrollbar_instance_memory_usage (Lisp_Object scrollbar_instance,
+ struct generic_usage_stats *gustats)
+{
+ struct scrollbar_instance_stats *stats =
+ (struct scrollbar_instance_stats *) gustats;
+ struct scrollbar_instance *inst = XSCROLLBAR_INSTANCE (scrollbar_instance);
+ struct device *d = FRAME_XDEVICE (inst->mirror->frame);
+ Bytecount total = 0;
+
+ if (HAS_DEVMETH_P (d, compute_scrollbar_instance_usage))
+ total += DEVMETH (d, compute_scrollbar_instance_usage, (d, inst,
+ &gustats->u));
+
+ stats->device_data = total;
}
#endif /* MEMORY_USAGE_STATS */
@@ -924,6 +941,13 @@
/************************************************************************/
void
+scrollbar_objects_create (void)
+{
+#ifdef MEMORY_USAGE_STATS
+ OBJECT_HAS_METHOD (scrollbar_instance, memory_usage);
+#endif
+}
+void
syms_of_scrollbar (void)
{
INIT_LISP_OBJECT (scrollbar_instance);
@@ -962,6 +986,12 @@
void
vars_of_scrollbar (void)
{
+#ifdef MEMORY_USAGE_STATS
+ OBJECT_HAS_PROPERTY
+ (scrollbar_instance, memusage_stats_list,
+ list1 (intern ("device-data")));
+#endif /* MEMORY_USAGE_STATS */
+
DEFVAR_LISP ("scrollbar-pointer-glyph", &Vscrollbar_pointer_glyph /*
*The shape of the mouse-pointer when over a scrollbar.
This is a glyph; use `set-glyph-image' to change it.
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/scrollbar.h
--- a/src/scrollbar.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/scrollbar.h Thu Mar 25 06:07:25 2010 -0500
@@ -1,5 +1,6 @@
/* Define scrollbar instance.
Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
+ Copyright (C) 2010 Ben Wing.
This file is part of XEmacs.
@@ -65,9 +66,8 @@
struct window_mirror *mirror,
int active, int horiz_only);
#ifdef MEMORY_USAGE_STATS
-int compute_scrollbar_instance_usage (struct device *d,
- struct scrollbar_instance *inst,
- struct usage_stats *ustats);
+Bytecount compute_all_scrollbar_instance_usage (struct scrollbar_instance *
+ inst);
#endif
extern Lisp_Object Vscrollbar_width, Vscrollbar_height;
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/symsinit.h
--- a/src/symsinit.h Wed Mar 24 01:22:51 2010 -0500
+++ b/src/symsinit.h Thu Mar 25 06:07:25 2010 -0500
@@ -209,6 +209,7 @@
Dump time and post-pdump-load-time. */
void buffer_objects_create (void);
+void casetab_objects_create (void);
void extent_objects_create (void);
void face_objects_create (void);
void frame_objects_create (void);
@@ -216,6 +217,7 @@
void hash_table_objects_create (void);
void lstream_objects_create (void);
void mule_charset_objects_create (void);
+void scrollbar_objects_create (void);
void ui_gtk_objects_create (void);
void window_objects_create (void);
@@ -354,6 +356,7 @@
void reinit_vars_of_bytecode (void);
void vars_of_callint (void);
EXTERN_C void vars_of_canna_api (void);
+void vars_of_casetab (void);
void vars_of_chartab (void);
void vars_of_cmdloop (void);
void vars_of_cmds (void);
diff -r 6c6d78781d59 -r 5ddbab03b0e6 src/window.c
--- a/src/window.c Wed Mar 24 01:22:51 2010 -0500
+++ b/src/window.c Thu Mar 25 06:07:25 2010 -0500
@@ -55,7 +55,7 @@
Lisp_Object Qdisplay_buffer;
#ifdef MEMORY_USAGE_STATS
-Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay;
+Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qredisplay_structs;
#ifdef HAVE_SCROLLBARS
Lisp_Object Qscrollbar_instances;
#endif
@@ -706,6 +706,18 @@
struct frame *f = XFRAME (w->frame);
if (f->mirror_dirty)
update_frame_window_mirror (f);
+ return find_window_mirror_internal (f->root_window,
+ XWINDOW_MIRROR (f->root_mirror), w);
+}
+
+/* Given a real window, return its mirror structure, if it exists.
+ Don't do any updating. */
+static struct window_mirror *
+find_window_mirror_maybe (struct window *w)
+{
+ struct frame *f = XFRAME (w->frame);
+ if (!WINDOW_MIRRORP (f->root_mirror))
+ return 0;
return find_window_mirror_internal (f->root_window,
XWINDOW_MIRROR (f->root_mirror), w);
}
@@ -5156,52 +5168,93 @@
#ifdef MEMORY_USAGE_STATS
+struct window_mirror_stats
+{
+ struct usage_stats u;
+ /* Ancilliary non-lisp */
+ Bytecount redisplay_structs;
+#ifdef HAVE_SCROLLBARS
+ /* Ancilliary Lisp */
+ Bytecount scrollbar;
+#endif
+};
+
struct window_stats
{
struct usage_stats u;
+ /* Ancillary non-Lisp */
+ Bytecount line_start;
+ /* The next two: ancillary non-Lisp under old-GC, ancillary Lisp under
+ NEW_GC */
Bytecount face;
Bytecount glyph;
- Bytecount line_start;
- Bytecount other_redisplay;
+ /* The next two are copied out of the window mirror, which is an ancillary
+ Lisp structure; the first is non-Lisp, the second Lisp, but from our
+ perspective, they are both counted as Lisp */
+ Bytecount redisplay_structs;
#ifdef HAVE_SCROLLBARS
Bytecount scrollbar;
#endif
+ /* Remaining memory associated with window mirror (ancillary Lisp) */
+ Bytecount window_mirror;
};
static void
compute_window_mirror_usage (struct window_mirror *mir,
- struct window_stats *stats,
- struct usage_stats *ustats)
-{
- if (!mir)
- return;
-#ifdef HAVE_SCROLLBARS
- {
- struct device *d = XDEVICE (FRAME_DEVICE (mir->frame));
-
- stats->scrollbar +=
- compute_scrollbar_instance_usage (d, mir->scrollbar_vertical_instance,
- ustats);
- stats->scrollbar +=
- compute_scrollbar_instance_usage (d, mir->scrollbar_horizontal_instance,
- ustats);
- }
+ struct window_mirror_stats *stats)
+{
+ stats->redisplay_structs =
+ compute_display_line_dynarr_usage (mir->current_display_lines, &stats->u)
+ +
+ compute_display_line_dynarr_usage (mir->desired_display_lines, &stats->u);
+#ifdef HAVE_SCROLLBARS
+ stats->scrollbar =
+ compute_all_scrollbar_instance_usage (mir->scrollbar_vertical_instance) +
+ compute_all_scrollbar_instance_usage (mir->scrollbar_horizontal_instance);
#endif /* HAVE_SCROLLBARS */
- stats->other_redisplay +=
- compute_display_line_dynarr_usage (mir->current_display_lines, ustats);
- stats->other_redisplay +=
- compute_display_line_dynarr_usage (mir->desired_display_lines, ustats);
+}
+
+
+static void
+window_mirror_memory_usage (Lisp_Object window_mirror,
+ struct generic_usage_stats *gustats)
+{
+ struct window_mirror_stats *stats = (struct window_mirror_stats *) gustats;
+
+ compute_window_mirror_usage (XWINDOW_MIRROR (window_mirror), stats);
}
static void
compute_window_usage (struct window *w, struct window_stats *stats,
struct usage_stats *ustats)
{
- stats->face += compute_face_cachel_usage (w->face_cachels, ustats);
- stats->glyph += compute_glyph_cachel_usage (w->glyph_cachels, ustats);
- stats->line_start +=
+ stats->line_start =
compute_line_start_cache_dynarr_usage (w->line_start_cache, ustats);
- compute_window_mirror_usage (find_window_mirror (w), stats, ustats);
+ stats->face = compute_face_cachel_usage (w->face_cachels,
+ IF_OLD_GC (ustats));
+ stats->glyph = compute_glyph_cachel_usage (w->glyph_cachels,
+ IF_OLD_GC (ustats));
+ {
+ struct window_mirror *wm;
+
+ wm = find_window_mirror_maybe (w);
+ if (wm)
+ {
+ struct generic_usage_stats gustats;
+ struct window_mirror_stats *wmstats;
+ Bytecount total;
+ total = lisp_object_memory_usage_full (wrap_window_mirror (wm),
+ NULL, NULL, NULL, &gustats);
+ wmstats = (struct window_mirror_stats *) &gustats;
+ stats->redisplay_structs = wmstats->redisplay_structs;
+ total -= stats->redisplay_structs;
+#ifdef HAVE_SCROLLBARS
+ stats->scrollbar = wmstats->scrollbar;
+ total -= stats->scrollbar;
+#endif
+ stats->window_mirror = total;
+ }
+ }
}
static void
@@ -5396,6 +5449,7 @@
{
#ifdef MEMORY_USAGE_STATS
OBJECT_HAS_METHOD (window, memory_usage);
+ OBJECT_HAS_METHOD (window_mirror, memory_usage);
#endif
}
@@ -5422,7 +5476,7 @@
#ifdef HAVE_SCROLLBARS
DEFSYMBOL (Qscrollbar_instances);
#endif
- DEFSYMBOL (Qother_redisplay);
+ DEFSYMBOL (Qredisplay_structs);
#endif
DEFSYMBOL (Qtruncate_partial_width_windows);
@@ -5516,14 +5570,31 @@
vars_of_window (void)
{
#ifdef MEMORY_USAGE_STATS
- OBJECT_HAS_PROPERTY
- (window, memusage_stats_list,
- listu (Qface_cache, Qglyph_cache,
- Qline_start_cache, Qother_redisplay,
-#ifdef HAVE_SCROLLBARS
- Qscrollbar_instances,
-#endif
- Qunbound));
+ Lisp_Object l;
+
+ l = listu (Qline_start_cache,
+#ifdef NEW_GC
+ Qt,
+#endif
+ Qface_cache, Qglyph_cache,
+#ifndef NEW_GC
+ Qt,
+#endif
+ Qredisplay_structs,
+#ifdef HAVE_SCROLLBARS
+ Qscrollbar_instances,
+#endif
+ intern ("window-mirror"),
+ Qunbound);
+
+ OBJECT_HAS_PROPERTY (window, memusage_stats_list, l);
+
+ l = listu (Qredisplay_structs,
+#ifdef HAVE_SCROLLBARS
+ Qt, Qscrollbar_instances,
+#endif
+ Qunbound);
+ OBJECT_HAS_PROPERTY (window_mirror, memusage_stats_list, l);
#endif /* MEMORY_USAGE_STATS */
DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
More information about the XEmacs-Patches
mailing list