Mercurial > hg > xemacs-beta
changeset 5160:ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
-------------------- ChangeLog entries follow: --------------------
lisp/ChangeLog addition:
2010-03-20 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 showing the overhead used with each type,
and add it into the grand total memory usage.
src/ChangeLog addition:
2010-03-20 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (init_lrecord_stats):
* alloc.c (free_normal_lisp_object):
* alloc.c (struct):
* alloc.c (clear_lrecord_stats):
* alloc.c (tick_lrecord_stats):
* alloc.c (COUNT_FROB_BLOCK_USAGE):
* alloc.c (COPY_INTO_LRECORD_STATS):
* alloc.c (sweep_strings):
* alloc.c (UNMARK_string):
* alloc.c (gc_sweep_1):
* alloc.c (finish_object_memory_usage_stats):
* alloc.c (object_memory_usage_stats):
* alloc.c (object_dead_p):
* alloc.c (fixed_type_block_overhead):
* alloc.c (lisp_object_storage_size):
* emacs.c (main_1):
* lisp.h:
* lrecord.h:
Export lisp_object_storage_size() and malloced_storage_size() even
when not MEMORY_USAGE_STATS, to get the non-MEMORY_USAGE_STATS
build to compile.
Don't export fixed_type_block_overhead() any more.
Some code cleanup, rearrangement, add some section headers.
Clean up various bugs especially involving computation of overhead
and double-counting certain usage in total_gc_usage. Add
statistics computing the overhead used by all types. Don't add a
special entry for string headers in the object-memory-usage-stats
because it's already present as just "string". But do count the
overhead used by long strings. Don't try to call the
memory_usage() methods when NEW_GC because there's nowhere obvious
in the sweep stage to make the calls.
* marker.c (compute_buffer_marker_usage):
Just use lisp_object_storage_size() rather than trying to
reimplement it.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 20 Mar 2010 20:20:30 -0500 |
parents | cb303ff63e76 |
children | 125f4119e64d |
files | lisp/ChangeLog lisp/diagnose.el src/ChangeLog src/alloc.c src/emacs.c src/lisp.h src/lrecord.h src/marker.c |
diffstat | 8 files changed, 288 insertions(+), 202 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/ChangeLog Fri Mar 19 17:02:11 2010 -0500 +++ b/lisp/ChangeLog Sat Mar 20 20:20:30 2010 -0500 @@ -1,3 +1,11 @@ +2010-03-20 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 showing the overhead used with each type, + and add it into the grand total memory usage. + 2010-03-19 Ben Wing <ben@xemacs.org> * diagnose.el (show-object-memory-usage-stats):
--- a/lisp/diagnose.el Fri Mar 19 17:02:11 2010 -0500 +++ b/lisp/diagnose.el Sat Mar 20 20:20:30 2010 -0500 @@ -159,9 +159,7 @@ (princ (format fmt (match-string 1 (symbol-name stat)) num))) - (when (eq stat 'long-strings-total-length) - (incf total num) - (princ (format fmt stat num)))) + ) (sixth (garbage-collect))) (princ "\n") (princ (format fmt "total" total)) @@ -186,77 +184,83 @@ (garbage-collect) (let ((buffer "*object memory usage statistics*") (plist (object-memory-usage-stats)) - (fmt "%-30s%10s%10s%18s\n") + (fmt "%-30s%10s%10s%10s%18s\n") (grandtotal 0) begin) (flet ((show-stats (match-string) - (princ (format fmt "object" "count" "storage" "non-Lisp storage")) - (princ (make-string 68 ?-)) + (princ (format fmt "object" "count" "storage" "overhead" + "non-Lisp storage")) + (princ (make-string 78 ?-)) (princ "\n") (let ((total-use 0) (total-non-lisp-use 0) (total-use-overhead 0) + (total-use-with-overhead 0) (total-count 0)) (map-plist #'(lambda (stat num) - (when (and (string-match match-string - (symbol-name stat)) - (let ((match (match-string - 1 (symbol-name stat)))) - (or (< (length match) 9) - (not (equal (substring match -9) - "-non-lisp"))))) - (let ((storage-use num) - (storage-use-overhead - (plist-get - plist - (intern (concat (match-string 1 (symbol-name stat)) - "-storage-including-overhead")))) - (non-lisp-storage - (or (plist-get - plist - (intern (concat (match-string 1 - (symbol-name stat)) - "-non-lisp-storage"))) - 0)) - - (storage-count - (or (loop for str in '("s-used" "es-used" "-used") - for val = (plist-get - plist - (intern - (concat (match-string - 1 (symbol-name stat)) - str))) - if val - return val) - (plist-get - plist - (intern - (concat (substring - (match-string 1 (symbol-name stat)) - 0 -1) - "ies-used"))) - ))) - (incf total-use storage-use) - (incf total-use-overhead (if storage-use-overhead - storage-use-overhead - storage-use)) - (incf total-non-lisp-use non-lisp-storage) - (incf total-count (or storage-count 0)) - (and (> storage-use 0) - (princ (format fmt - (match-string 1 (symbol-name stat)) - (or storage-count "unknown") - storage-use - non-lisp-storage)))))) + (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")))) + (let* ((storage-use num) + (storage-use-overhead + (or (plist-get + plist + (intern (concat symmatch + "-storage-overhead"))) + 0)) + (storage-use-with-overhead + (or (plist-get + plist + (intern (concat + symmatch + "-storage-including-overhead"))) + (+ storage-use storage-use-overhead))) + (storage-use-overhead + (- storage-use-with-overhead storage-use)) + (non-lisp-storage + (or (plist-get + plist + (intern (concat symmatch + "-non-lisp-storage"))) + 0)) + (storage-count + (or (loop for str in '("s-used" "es-used" "-used") + for val = (plist-get + plist + (intern + (concat symmatch str))) + if val + return val) + (plist-get + plist + (intern + (concat (substring symmatch 0 -1) + "ies-used"))) + ))) + (incf total-use storage-use) + (incf total-use-overhead storage-use-overhead) + (incf total-use-with-overhead storage-use-with-overhead) + (incf total-non-lisp-use non-lisp-storage) + (incf total-count (or storage-count 0)) + (and (> storage-use-with-overhead 0) + (princ (format fmt symmatch + (or storage-count "unknown") + storage-use + storage-use-overhead + non-lisp-storage))))))) plist) (princ "\n") (princ (format fmt "total" - total-count total-use-overhead total-non-lisp-use)) - (incf grandtotal total-use-overhead) + total-count total-use total-use-overhead + total-non-lisp-use)) + (incf grandtotal total-use-with-overhead) + (incf grandtotal total-non-lisp-use) (when-fboundp #'sort-numeric-fields - (sort-numeric-fields -2 + (sort-numeric-fields -3 (save-excursion (goto-char begin) (forward-line 3)
--- a/src/ChangeLog Fri Mar 19 17:02:11 2010 -0500 +++ b/src/ChangeLog Sat Mar 20 20:20:30 2010 -0500 @@ -1,3 +1,45 @@ +2010-03-20 Ben Wing <ben@xemacs.org> + + * alloc.c: + * alloc.c (init_lrecord_stats): + * alloc.c (free_normal_lisp_object): + * alloc.c (struct): + * alloc.c (clear_lrecord_stats): + * alloc.c (tick_lrecord_stats): + * alloc.c (COUNT_FROB_BLOCK_USAGE): + * alloc.c (COPY_INTO_LRECORD_STATS): + * alloc.c (sweep_strings): + * alloc.c (UNMARK_string): + * alloc.c (gc_sweep_1): + * alloc.c (finish_object_memory_usage_stats): + * alloc.c (object_memory_usage_stats): + * alloc.c (object_dead_p): + * alloc.c (fixed_type_block_overhead): + * alloc.c (lisp_object_storage_size): + * emacs.c (main_1): + * lisp.h: + * lrecord.h: + Export lisp_object_storage_size() and malloced_storage_size() even + when not MEMORY_USAGE_STATS, to get the non-MEMORY_USAGE_STATS + build to compile. + + Don't export fixed_type_block_overhead() any more. + + Some code cleanup, rearrangement, add some section headers. + + Clean up various bugs especially involving computation of overhead + and double-counting certain usage in total_gc_usage. Add + statistics computing the overhead used by all types. Don't add a + special entry for string headers in the object-memory-usage-stats + because it's already present as just "string". But do count the + overhead used by long strings. Don't try to call the + memory_usage() methods when NEW_GC because there's nowhere obvious + in the sweep stage to make the calls. + + * marker.c (compute_buffer_marker_usage): + Just use lisp_object_storage_size() rather than trying to + reimplement it. + 2010-03-19 Ben Wing <ben@xemacs.org> * alloc.c:
--- a/src/alloc.c Fri Mar 19 17:02:11 2010 -0500 +++ b/src/alloc.c Sat Mar 20 20:20:30 2010 -0500 @@ -113,6 +113,15 @@ UID is only 20 bits in old-GC, and 22 in NEW_GC.) */ int lrecord_uid_counter[countof (lrecord_implementations_table)]; +#ifndef USE_KKCC +/* Object marker functions are in the lrecord_implementation structure. + But copying them to a parallel array is much more cache-friendly. + This hack speeds up (garbage-collect) by about 5%. */ +Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); +#endif /* not USE_KKCC */ + +struct gcpro *gcprolist; + /* Non-zero means we're in the process of doing the dump */ int purify_flag; @@ -517,7 +526,7 @@ } lrecord_stats [countof (lrecord_implementations_table)]; void -init_lrecord_stats () +init_lrecord_stats (void) { xzero (lrecord_stats); } @@ -845,37 +854,6 @@ zero_sized_lisp_object (obj, lisp_object_size (obj)); } -#ifdef MEMORY_USAGE_STATS - -Bytecount -lisp_object_storage_size (Lisp_Object obj, struct usage_stats *ustats) -{ -#ifndef NEW_GC - const struct lrecord_implementation *imp = - XRECORD_LHEADER_IMPLEMENTATION (obj); -#endif /* not NEW_GC */ - Bytecount size = lisp_object_size (obj); - -#ifdef NEW_GC - return mc_alloced_storage_size (size, ustats); -#else - if (imp->frob_block_p) - { - Bytecount overhead = fixed_type_block_overhead (size); - if (ustats) - { - ustats->was_requested += size; - ustats->malloc_overhead += overhead; - } - return size + overhead; - } - else - return malloced_storage_size (XPNTR (obj), size, ustats); -#endif -} - -#endif /* MEMORY_USAGE_STATS */ - void free_normal_lisp_object (Lisp_Object obj) { @@ -3390,18 +3368,9 @@ /************************************************************************/ -/* Garbage Collection */ +/* Staticpro, MCpro */ /************************************************************************/ -#ifndef USE_KKCC -/* Object marker functions are in the lrecord_implementation structure. - But copying them to a parallel array is much more cache-friendly. - This hack speeds up (garbage-collect) by about 5%. */ -Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); -#endif /* not USE_KKCC */ - -struct gcpro *gcprolist; - /* We want the staticpro list relocated, but not the pointers found therein, because they refer to locations in the global data segment, not in the heap; we only dump heap objects. Hence we use a trivial @@ -3539,10 +3508,6 @@ #endif /* not DEBUG_XEMACS */ - - - - #ifdef NEW_GC static const struct memory_description mcpro_description_1[] = { { XD_END } @@ -3604,47 +3569,102 @@ #endif /* not DEBUG_XEMACS */ #endif /* NEW_GC */ + +/************************************************************************/ +/* Allocation Statistics */ +/************************************************************************/ #ifndef NEW_GC static int gc_count_num_short_string_in_use; static Bytecount gc_count_string_total_size; static Bytecount gc_count_short_string_total_size; +static Bytecount gc_count_long_string_storage_including_overhead; /* static int gc_count_total_records_used, gc_count_records_total_size; */ -/* stats on lcrecords in use - kinda kludgy */ +/* stats on objects in use */ static struct { - int instances_in_use; - int bytes_in_use; - int instances_freed; - int bytes_freed; - int instances_on_free_list; - int bytes_on_free_list; + Elemcount instances_in_use; + Bytecount bytes_in_use; + Bytecount bytes_in_use_overhead; + Elemcount instances_freed; + Bytecount bytes_freed; + Bytecount bytes_freed_overhead; + Elemcount instances_on_free_list; + Bytecount bytes_on_free_list; + Bytecount bytes_on_free_list_overhead; #ifdef MEMORY_USAGE_STATS Bytecount nonlisp_bytes_in_use; struct generic_usage_stats stats; #endif } lrecord_stats [countof (lrecord_implementations_table)]; +static void +clear_lrecord_stats (void) +{ + xzero (lrecord_stats); + gc_count_num_short_string_in_use = 0; + gc_count_string_total_size = 0; + gc_count_short_string_total_size = 0; + gc_count_long_string_storage_including_overhead = 0; +} + +/* Keep track of extra statistics for strings -- length of the string + characters for short and long strings, number of short and long strings. */ +static void +tick_string_stats (Lisp_String *p, int from_sweep) +{ + Bytecount size = p->size_; + gc_count_string_total_size += size; + if (!BIG_STRING_SIZE_P (size)) + { + gc_count_short_string_total_size += size; + gc_count_num_short_string_in_use++; + } + else + gc_count_long_string_storage_including_overhead += + malloced_storage_size (p->data_, p->size_, NULL); + /* During the sweep stage, we count the total number of strings in use. + This gets those not stored in pdump storage. For pdump storage, we + need to bump the number of strings in use so as to get an accurate + count of all strings in use (pdump or not). But don't do this when + called from the sweep stage, or we will double-count. */ + if (!from_sweep) + gc_count_num_string_in_use++; +} + +/* As objects are sweeped, we record statistics about their memory usage. + Currently, all lcrecords are processed this way as well as any frob-block + objects that were saved and restored as a result of the pdump process. + (See pdump_objects_unmark().) Other frob-block objects do NOT get their + statistics noted this way -- instead, as the frob blocks are swept, + COPY_INTO_LRECORD_STATS() is called, and notes statistics about the + frob blocks. */ + void tick_lrecord_stats (const struct lrecord_header *h, enum lrecord_alloc_status status) { int type_index = h->type; - Bytecount sz = detagged_lisp_object_size (h); + Bytecount obj = wrap_pointer_1 (h); + Bytecount sz = lisp_object_size (obj); + Bytecount sz_with_overhead = lisp_object_storage_size (obj, NULL); + Bytecount overhead = sz_with_overhead - sz; switch (status) { case ALLOC_IN_USE: lrecord_stats[type_index].instances_in_use++; lrecord_stats[type_index].bytes_in_use += sz; + lrecord_stats[type_index].bytes_in_use_overhead += overhead; + if (STRINGP (obj)) + tick_string_stats (XSTRING (obj), 0); #ifdef MEMORY_USAGE_STATS { struct generic_usage_stats stats; - Lisp_Object obj = wrap_pointer_1 (h); if (HAS_OBJECT_METH_P (obj, memory_usage)) { int i; @@ -3661,10 +3681,12 @@ case ALLOC_FREE: lrecord_stats[type_index].instances_freed++; lrecord_stats[type_index].bytes_freed += sz; + lrecord_stats[type_index].bytes_freed_overhead += overhead; break; case ALLOC_ON_FREE_LIST: lrecord_stats[type_index].instances_on_free_list++; lrecord_stats[type_index].bytes_on_free_list += sz; + lrecord_stats[type_index].bytes_on_free_list_overhead += overhead; break; default: ABORT (); @@ -3682,9 +3704,14 @@ else tick_lrecord_stats (h, free_p ? ALLOC_FREE : ALLOC_IN_USE); } + #endif /* not NEW_GC */ +/************************************************************************/ +/* Garbage Collection -- Sweep/Compact */ +/************************************************************************/ + #ifndef NEW_GC /* Free all unmarked records */ static void @@ -3745,19 +3772,26 @@ /* *total = total_size; */ } +static Bytecount fixed_type_block_overhead (Bytecount size, + Bytecount per_block); + /* And the Lord said: Thou shalt use the `c-backslash-region' command to make macros prettier. */ #define COUNT_FROB_BLOCK_USAGE(type) \ EMACS_INT s = 0; \ + EMACS_INT s_overhead = 0; \ struct type##_block *x = current_##type##_block; \ while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; } \ + s_overhead = fixed_type_block_overhead (s, sizeof (struct type##_block)); \ DO_NOTHING #define COPY_INTO_LRECORD_STATS(type) \ do { \ COUNT_FROB_BLOCK_USAGE (type); \ lrecord_stats[lrecord_type_##type].bytes_in_use += s; \ + lrecord_stats[lrecord_type_##type].bytes_in_use_overhead += \ + s_overhead; \ lrecord_stats[lrecord_type_##type].instances_on_free_list += \ gc_count_num_##type##_freelist; \ lrecord_stats[lrecord_type_##type].instances_in_use += \ @@ -4423,20 +4457,12 @@ static void sweep_strings (void) { - int num_small_used = 0; - Bytecount num_small_bytes = 0, num_bytes = 0; int debug = debug_string_purity; #define UNMARK_string(ptr) do { \ Lisp_String *p = (ptr); \ - Bytecount size = p->size_; \ UNMARK_RECORD_HEADER (&(p->u.lheader)); \ - num_bytes += size; \ - if (!BIG_STRING_SIZE_P (size)) \ - { \ - num_small_bytes += size; \ - num_small_used++; \ - } \ + tick_string_stats (p, 1); \ if (debug) \ debug_string_purity_print (wrap_string (p)); \ } while (0) @@ -4447,10 +4473,6 @@ } while (0) SWEEP_FIXED_TYPE_BLOCK_1 (string, Lisp_String, u.lheader); - - gc_count_num_short_string_in_use = num_small_used; - gc_count_string_total_size = num_bytes; - gc_count_short_string_total_size = num_small_bytes; } #endif /* not NEW_GC */ @@ -4460,7 +4482,7 @@ { /* Reset all statistics to 0. They will be incremented when sweeping lcrecords, frob-block lrecords and dumped objects. */ - xzero (lrecord_stats); + clear_lrecord_stats (); /* Free all unmarked records. Do this at the very beginning, before anything else, so that the finalize methods can safely @@ -4542,8 +4564,11 @@ #endif } #endif /* not NEW_GC */ + -/* Clearing for disksave. */ +/************************************************************************/ +/* "Disksave Finalization" -- Preparing for Dumping */ +/************************************************************************/ void disksave_object_finalization (void) @@ -4679,7 +4704,13 @@ void finish_object_memory_usage_stats (void) { -#ifdef MEMORY_USAGE_STATS + /* Here we add up the aggregate values for each statistic, previously + computed during tick_lrecord_stats(), to get a single combined value + of non-Lisp memory usage for all objects of each type. We can't + do this if NEW_GC because nothing like tick_lrecord_stats() gets + called -- instead, statistics are computed when objects are allocated, + which is too early to be calling the memory_usage() method. */ +#if defined (MEMORY_USAGE_STATS) && !defined (NEW_GC) int i; for (i = 0; i < countof (lrecord_implementations_table); i++) { @@ -4692,7 +4723,7 @@ lrecord_stats[i].stats.othervals[j]; } } -#endif /* MEMORY_USAGE_STATS */ +#endif /* defined (MEMORY_USAGE_STATS) && !defined (NEW_GC) */ } static Lisp_Object @@ -4733,38 +4764,6 @@ #else /* not NEW_GC */ -#define HACK_O_MATIC(type, name, pl) \ -do { \ - COUNT_FROB_BLOCK_USAGE (type); \ - tgu_val += s; \ - (pl) = gc_plist_hack ((name), s, (pl)); \ -} while (0) - -#define FROB(type) \ -do { \ - COUNT_FROB_BLOCK_USAGE (type); \ - tgu_val += s; \ -} while (0) - - FROB (extent); - FROB (event); - FROB (marker); - FROB (float); -#ifdef HAVE_BIGNUM - FROB (bignum); -#endif /* HAVE_BIGNUM */ -#ifdef HAVE_RATIO - FROB (ratio); -#endif /* HAVE_RATIO */ -#ifdef HAVE_BIGFLOAT - FROB (bigfloat); -#endif /* HAVE_BIGFLOAT */ - FROB (compiled_function); - FROB (symbol); - FROB (cons); - -#undef FROB - for (i = 0; i < lrecord_type_count; i++) { if (lrecord_stats[i].bytes_in_use != 0 @@ -4774,9 +4773,13 @@ Ascbyte buf[255]; const Ascbyte *name = lrecord_implementations_table[i]->name; + sprintf (buf, "%s-storage-overhead", name); + pl = gc_plist_hack (buf, lrecord_stats[i].bytes_in_use_overhead, pl); + tgu_val += lrecord_stats[i].bytes_in_use_overhead; sprintf (buf, "%s-storage", name); pl = gc_plist_hack (buf, lrecord_stats[i].bytes_in_use, pl); tgu_val += lrecord_stats[i].bytes_in_use; +#ifdef MEMORY_USAGE_STATS if (lrecord_stats[i].nonlisp_bytes_in_use) { sprintf (buf, "%s-non-lisp-storage", name); @@ -4784,6 +4787,7 @@ pl); tgu_val += lrecord_stats[i].nonlisp_bytes_in_use; } +#endif /* MEMORY_USAGE_STATS */ pluralize_and_append (buf, name, "-freed"); if (lrecord_stats[i].instances_freed != 0) pl = gc_plist_hack (buf, lrecord_stats[i].instances_freed, pl); @@ -4796,22 +4800,33 @@ } } - HACK_O_MATIC (string, "string-header-storage", pl); + pl = gc_plist_hack ("long-string-chars-storage-overhead", + gc_count_long_string_storage_including_overhead - + (gc_count_string_total_size + - gc_count_short_string_total_size), pl); + pl = gc_plist_hack ("long-string-chars-storage", + gc_count_string_total_size + - gc_count_short_string_total_size, pl); + do + { + COUNT_FROB_BLOCK_USAGE (string_chars); + tgu_val += s + s_overhead; + pl = gc_plist_hack ("short-string-chars-storage-overhead", s_overhead, pl); + pl = gc_plist_hack ("short-string-chars-storage", s, pl); + } + while (0); + pl = gc_plist_hack ("long-strings-total-length", gc_count_string_total_size - gc_count_short_string_total_size, pl); - HACK_O_MATIC (string_chars, "short-string-storage", pl); pl = gc_plist_hack ("short-strings-total-length", gc_count_short_string_total_size, pl); - pl = gc_plist_hack ("strings-free", gc_count_num_string_freelist, pl); pl = gc_plist_hack ("long-strings-used", gc_count_num_string_in_use - gc_count_num_short_string_in_use, pl); pl = gc_plist_hack ("short-strings-used", gc_count_num_short_string_in_use, pl); -#undef HACK_O_MATIC - #endif /* NEW_GC */ if (set_total_gc_usage) @@ -5107,7 +5122,6 @@ need_to_signal_post_gc; } - int object_dead_p (Lisp_Object obj) { @@ -5120,7 +5134,7 @@ (EXTENTP (obj) && !EXTENT_LIVE_P (XEXTENT (obj)))); } -#ifdef MEMORY_USAGE_STATS +#ifdef ALLOC_TYPE_STATS /* Attempt to determine the actual amount of space that is used for the block allocated starting at PTR, supposedly of size "CLAIMED_SIZE". @@ -5214,25 +5228,60 @@ } #ifndef NEW_GC -Bytecount -fixed_type_block_overhead (Bytecount size) -{ - Bytecount per_block = TYPE_ALLOC_SIZE (cons, unsigned char); +static Bytecount +fixed_type_block_overhead (Bytecount size, Bytecount per_block) +{ Bytecount overhead = 0; Bytecount storage_size = malloced_storage_size (0, per_block, 0); while (size >= per_block) { size -= per_block; - overhead += sizeof (void *) + per_block - storage_size; + overhead += storage_size - per_block; } if (rand () % per_block < size) - overhead += sizeof (void *) + per_block - storage_size; + overhead += storage_size - per_block; return overhead; } #endif /* not NEW_GC */ -#endif /* MEMORY_USAGE_STATS */ + +Bytecount +lisp_object_storage_size (Lisp_Object obj, struct usage_stats *ustats) +{ +#ifndef NEW_GC + const struct lrecord_implementation *imp = + XRECORD_LHEADER_IMPLEMENTATION (obj); +#endif /* not NEW_GC */ + Bytecount size = lisp_object_size (obj); + +#ifdef NEW_GC + return mc_alloced_storage_size (size, ustats); +#else + if (imp->frob_block_p) + { + Bytecount overhead = + /* #### Always using cons_block is incorrect but close; only + string_chars_block is significantly different in size, and + it won't ever be seen in this function */ + fixed_type_block_overhead (size, sizeof (struct cons_block)); + if (ustats) + { + ustats->was_requested += size; + ustats->malloc_overhead += overhead; + } + return size + overhead; + } + else + return malloced_storage_size (XPNTR (obj), size, ustats); +#endif +} + +#endif /* ALLOC_TYPE_STATS */ +/************************************************************************/ +/* Initialization */ +/************************************************************************/ + /* Initialization */ static void common_init_alloc_early (void)
--- a/src/emacs.c Fri Mar 19 17:02:11 2010 -0500 +++ b/src/emacs.c Sat Mar 20 20:20:30 2010 -0500 @@ -1767,7 +1767,9 @@ glyph_objects_create (); hash_table_objects_create (); lstream_objects_create (); +#ifdef MULE mule_charset_objects_create (); +#endif #ifdef HAVE_GTK ui_gtk_objects_create (); #endif
--- a/src/lisp.h Fri Mar 19 17:02:11 2010 -0500 +++ b/src/lisp.h Sat Mar 20 20:20:30 2010 -0500 @@ -1592,8 +1592,6 @@ /* misc */ /* ------------------------------- */ -#ifdef MEMORY_USAGE_STATS - /* This structure is used to keep statistics on the amount of memory in use. @@ -1627,8 +1625,6 @@ Bytecount othervals[32]; }; -#endif /* MEMORY_USAGE_STATS */ - /************************************************************************/ /* Definition of Lisp_Object data type */ @@ -4839,10 +4835,7 @@ extern Lisp_Object Qpost_gc_hook, Qgarbage_collecting; void recompute_funcall_allocation_flag (void); -#ifdef MEMORY_USAGE_STATS Bytecount malloced_storage_size (void *, Bytecount, struct usage_stats *); -Bytecount fixed_type_block_overhead (Bytecount); -#endif #ifdef EVENT_DATA_AS_OBJECTS Lisp_Object make_key_data (void); @@ -5935,7 +5928,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 -int compute_buffer_marker_usage (struct buffer *, struct usage_stats *); +Bytecount compute_buffer_marker_usage (struct buffer *, struct usage_stats *); #endif void init_buffer_markers (struct buffer *b); void uninit_buffer_markers (struct buffer *b);
--- a/src/lrecord.h Fri Mar 19 17:02:11 2010 -0500 +++ b/src/lrecord.h Sat Mar 20 20:20:30 2010 -0500 @@ -2022,10 +2022,8 @@ MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src); MODULE_API void zero_sized_lisp_object (Lisp_Object obj, Bytecount size); MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj); -#ifdef MEMORY_USAGE_STATS Bytecount lisp_object_storage_size (Lisp_Object obj, struct usage_stats *ustats); -#endif /* MEMORY_USAGE_STATS */ void free_normal_lisp_object (Lisp_Object obj);
--- a/src/marker.c Fri Mar 19 17:02:11 2010 -0500 +++ b/src/marker.c Sat Mar 20 20:20:30 2010 -0500 @@ -497,25 +497,15 @@ #ifdef MEMORY_USAGE_STATS -int +Bytecount compute_buffer_marker_usage (struct buffer *b, struct usage_stats *ustats) { Lisp_Marker *m; - int total = 0; - int overhead; + Bytecount total = 0; for (m = BUF_MARKERS (b); m; m = m->next) - total += sizeof (Lisp_Marker); - ustats->was_requested += total; -#ifdef NEW_GC - overhead = mc_alloced_storage_size (total, 0) - total; -#else /* not NEW_GC */ - overhead = fixed_type_block_overhead (total); -#endif /* not NEW_GC */ - /* #### claiming this is all malloc overhead is not really right, - but it has to go somewhere. */ - ustats->malloc_overhead += overhead; - return total + overhead; + total += lisp_object_storage_size (wrap_marker (m), ustats); + return total; } #endif /* MEMORY_USAGE_STATS */