aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorDmitry Antipov2012-07-18 09:44:36 +0400
committerDmitry Antipov2012-07-18 09:44:36 +0400
commit3ab6e069695d0dd5bb77133a89f858190ab8550a (patch)
treebd50490ec50ec8d5f72625fd38840d1283983561 /src/alloc.c
parent0a60bc107123321438fc1320ab34fcf588ec7128 (diff)
downloademacs-3ab6e069695d0dd5bb77133a89f858190ab8550a.tar.gz
emacs-3ab6e069695d0dd5bb77133a89f858190ab8550a.zip
Return more descriptive data from Fgarbage_collect.
Suggested by Stefan Monnier in http://lists.gnu.org/archive/html/emacs-devel/2012-07/msg00369.html. * src/alloc.c (bounded_number): New function. (total_buffers, total_vectors): New variable. (total_string_size): Rename to total_string_bytes, adjust users. (total_vector_size): Rename to total_vector_bytes, adjust users. (sweep_vectors): Account total_vectors and total_vector_bytes. (Fgarbage_collect): New return value. Adjust documentation. (gc_sweep): Account total_buffers. (Fmemory_free, Fmemory_use_counts): Use bounded_number. (VECTOR_SIZE): Remove. * src/data.c (Qfloat, Qvector, Qsymbol, Qstring, Qcons): Make global. (Qinterval, Qmisc): New symbols. (syms_of_data): Initialize them. * src/lisp.h (Qinterval, Qsymbol, Qstring, Qmisc, Qvector, Qfloat) (Qcons, Qbuffer): New declarations. * lisp/emacs-lisp/chart.el (chart-emacs-storage): Change to reflect new format of data returned by Fgarbage_collect.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c149
1 files changed, 92 insertions, 57 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 7ab3f7b5e9c..b891d32d164 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -189,9 +189,9 @@ int abort_on_gc;
189 189
190/* Number of live and free conses etc. */ 190/* Number of live and free conses etc. */
191 191
192static EMACS_INT total_conses, total_markers, total_symbols, total_vector_size; 192static EMACS_INT total_conses, total_markers, total_symbols, total_buffers;
193static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; 193static EMACS_INT total_free_conses, total_free_markers, total_free_symbols;
194static EMACS_INT total_free_floats, total_floats, total_free_vector_bytes; 194static EMACS_INT total_free_floats, total_floats;
195 195
196/* Points to memory space allocated as "spare", to be freed if we run 196/* Points to memory space allocated as "spare", to be freed if we run
197 out of memory. We keep one large block, four cons-blocks, and 197 out of memory. We keep one large block, four cons-blocks, and
@@ -1708,7 +1708,7 @@ static EMACS_INT total_strings, total_free_strings;
1708 1708
1709/* Number of bytes used by live strings. */ 1709/* Number of bytes used by live strings. */
1710 1710
1711static EMACS_INT total_string_size; 1711static EMACS_INT total_string_bytes;
1712 1712
1713/* Given a pointer to a Lisp_String S which is on the free-list 1713/* Given a pointer to a Lisp_String S which is on the free-list
1714 string_free_list, return a pointer to its successor in the 1714 string_free_list, return a pointer to its successor in the
@@ -2081,7 +2081,7 @@ sweep_strings (void)
2081 2081
2082 string_free_list = NULL; 2082 string_free_list = NULL;
2083 total_strings = total_free_strings = 0; 2083 total_strings = total_free_strings = 0;
2084 total_string_size = 0; 2084 total_string_bytes = 0;
2085 2085
2086 /* Scan strings_blocks, free Lisp_Strings that aren't marked. */ 2086 /* Scan strings_blocks, free Lisp_Strings that aren't marked. */
2087 for (b = string_blocks; b; b = next) 2087 for (b = string_blocks; b; b = next)
@@ -2107,7 +2107,7 @@ sweep_strings (void)
2107 UNMARK_BALANCE_INTERVALS (s->intervals); 2107 UNMARK_BALANCE_INTERVALS (s->intervals);
2108 2108
2109 ++total_strings; 2109 ++total_strings;
2110 total_string_size += STRING_BYTES (s); 2110 total_string_bytes += STRING_BYTES (s);
2111 } 2111 }
2112 else 2112 else
2113 { 2113 {
@@ -2957,6 +2957,14 @@ static struct Lisp_Vector *large_vectors;
2957 2957
2958Lisp_Object zero_vector; 2958Lisp_Object zero_vector;
2959 2959
2960/* Number of live vectors. */
2961
2962static EMACS_INT total_vectors;
2963
2964/* Number of bytes used by live and free vectors. */
2965
2966static EMACS_INT total_vector_bytes, total_free_vector_bytes;
2967
2960/* Get a new vector block. */ 2968/* Get a new vector block. */
2961 2969
2962static struct vector_block * 2970static struct vector_block *
@@ -3047,12 +3055,6 @@ allocate_vector_from_block (size_t nbytes)
3047 return vector; 3055 return vector;
3048 } 3056 }
3049 3057
3050/* Return how many Lisp_Objects can be stored in V. */
3051
3052#define VECTOR_SIZE(v) ((v)->header.size & PSEUDOVECTOR_FLAG ? \
3053 (PSEUDOVECTOR_SIZE_MASK & (v)->header.size) : \
3054 (v)->header.size)
3055
3056/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ 3058/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
3057 3059
3058#define VECTOR_IN_BLOCK(vector, block) \ 3060#define VECTOR_IN_BLOCK(vector, block) \
@@ -3077,7 +3079,7 @@ sweep_vectors (void)
3077 struct vector_block *block = vector_blocks, **bprev = &vector_blocks; 3079 struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
3078 struct Lisp_Vector *vector, *next, **vprev = &large_vectors; 3080 struct Lisp_Vector *vector, *next, **vprev = &large_vectors;
3079 3081
3080 total_free_vector_bytes = total_vector_size = 0; 3082 total_vectors = total_vector_bytes = total_free_vector_bytes = 0;
3081 memset (vector_free_lists, 0, sizeof (vector_free_lists)); 3083 memset (vector_free_lists, 0, sizeof (vector_free_lists));
3082 3084
3083 /* Looking through vector blocks. */ 3085 /* Looking through vector blocks. */
@@ -3092,7 +3094,8 @@ sweep_vectors (void)
3092 if (VECTOR_MARKED_P (vector)) 3094 if (VECTOR_MARKED_P (vector))
3093 { 3095 {
3094 VECTOR_UNMARK (vector); 3096 VECTOR_UNMARK (vector);
3095 total_vector_size += VECTOR_SIZE (vector); 3097 total_vectors++;
3098 total_vector_bytes += vector->header.next.nbytes;
3096 next = ADVANCE (vector, vector->header.next.nbytes); 3099 next = ADVANCE (vector, vector->header.next.nbytes);
3097 } 3100 }
3098 else 3101 else
@@ -3148,7 +3151,12 @@ sweep_vectors (void)
3148 if (VECTOR_MARKED_P (vector)) 3151 if (VECTOR_MARKED_P (vector))
3149 { 3152 {
3150 VECTOR_UNMARK (vector); 3153 VECTOR_UNMARK (vector);
3151 total_vector_size += VECTOR_SIZE (vector); 3154 total_vectors++;
3155 /* All pseudovectors are small enough to be allocated from
3156 vector blocks. This code should be redesigned if some
3157 pseudovector type grows beyond VBLOCK_BYTES_MAX. */
3158 eassert (!(vector->header.size & PSEUDOVECTOR_FLAG));
3159 total_vector_bytes += header_size + vector->header.size * word_size;
3152 vprev = &vector->header.next.vector; 3160 vprev = &vector->header.next.vector;
3153 } 3161 }
3154 else 3162 else
@@ -5339,16 +5347,28 @@ inhibit_garbage_collection (void)
5339 return count; 5347 return count;
5340} 5348}
5341 5349
5350/* Used to avoid possible overflows when
5351 converting from C to Lisp integers. */
5352
5353static inline Lisp_Object
5354bounded_number (EMACS_INT number)
5355{
5356 return make_number (min (MOST_POSITIVE_FIXNUM, number));
5357}
5342 5358
5343DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", 5359DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
5344 doc: /* Reclaim storage for Lisp objects no longer needed. 5360 doc: /* Reclaim storage for Lisp objects no longer needed.
5345Garbage collection happens automatically if you cons more than 5361Garbage collection happens automatically if you cons more than
5346`gc-cons-threshold' bytes of Lisp data since previous garbage collection. 5362`gc-cons-threshold' bytes of Lisp data since previous garbage collection.
5347`garbage-collect' normally returns a list with info on amount of space in use: 5363`garbage-collect' normally returns a list with info on amount of space in use:
5348 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) 5364 ((CONS INTERNAL-SIZE USED-CONSES FREE-CONSES)
5349 (USED-MISCS . FREE-MISCS) USED-STRING-CHARS USED-VECTOR-SLOTS 5365 (SYMBOL INTERNAL-SIZE USED-SYMBOLS FREE-SYMBOLS)
5350 (USED-FLOATS . FREE-FLOATS) (USED-INTERVALS . FREE-INTERVALS) 5366 (MISC INTERNAL-SIZE USED-MISCS FREE-MISCS)
5351 (USED-STRINGS . FREE-STRINGS)) 5367 (STRING INTERNAL-SIZE USED-STRINGS USED-STRING-BYTES FREE-STRING)
5368 (VECTOR INTERNAL-SIZE USED-VECTORS USED-VECTOR-BYTES FREE-VECTOR-BYTES)
5369 (FLOAT INTERNAL-SIZE USED-FLOATS FREE-FLOATS)
5370 (INTERVAL INTERNAL-SIZE USED-INTERVALS FREE-INTERVALS)
5371 (BUFFER INTERNAL-SIZE USED-BUFFERS))
5352However, if there was overflow in pure space, `garbage-collect' 5372However, if there was overflow in pure space, `garbage-collect'
5353returns nil, because real GC can't be done. 5373returns nil, because real GC can't be done.
5354See Info node `(elisp)Garbage Collection'. */) 5374See Info node `(elisp)Garbage Collection'. */)
@@ -5595,8 +5615,8 @@ See Info node `(elisp)Garbage Collection'. */)
5595 tot += total_conses * sizeof (struct Lisp_Cons); 5615 tot += total_conses * sizeof (struct Lisp_Cons);
5596 tot += total_symbols * sizeof (struct Lisp_Symbol); 5616 tot += total_symbols * sizeof (struct Lisp_Symbol);
5597 tot += total_markers * sizeof (union Lisp_Misc); 5617 tot += total_markers * sizeof (union Lisp_Misc);
5598 tot += total_string_size; 5618 tot += total_string_bytes;
5599 tot += total_vector_size * sizeof (Lisp_Object); 5619 tot += total_vector_bytes;
5600 tot += total_floats * sizeof (struct Lisp_Float); 5620 tot += total_floats * sizeof (struct Lisp_Float);
5601 tot += total_intervals * sizeof (struct interval); 5621 tot += total_intervals * sizeof (struct interval);
5602 tot += total_strings * sizeof (struct Lisp_String); 5622 tot += total_strings * sizeof (struct Lisp_String);
@@ -5621,20 +5641,38 @@ See Info node `(elisp)Garbage Collection'. */)
5621 5641
5622 unbind_to (count, Qnil); 5642 unbind_to (count, Qnil);
5623 5643
5624 total[0] = Fcons (make_number (total_conses), 5644 total[0] = list4 (Qcons, make_number (sizeof (struct Lisp_Cons)),
5625 make_number (total_free_conses)); 5645 bounded_number (total_conses),
5626 total[1] = Fcons (make_number (total_symbols), 5646 bounded_number (total_free_conses));
5627 make_number (total_free_symbols)); 5647
5628 total[2] = Fcons (make_number (total_markers), 5648 total[1] = list4 (Qsymbol, make_number (sizeof (struct Lisp_Symbol)),
5629 make_number (total_free_markers)); 5649 bounded_number (total_symbols),
5630 total[3] = make_number (total_string_size); 5650 bounded_number (total_free_symbols));
5631 total[4] = make_number (total_vector_size); 5651
5632 total[5] = Fcons (make_number (total_floats), 5652 total[2] = list4 (Qmisc, make_number (sizeof (union Lisp_Misc)),
5633 make_number (total_free_floats)); 5653 bounded_number (total_markers),
5634 total[6] = Fcons (make_number (total_intervals), 5654 bounded_number (total_free_markers));
5635 make_number (total_free_intervals)); 5655
5636 total[7] = Fcons (make_number (total_strings), 5656 total[3] = list5 (Qstring, make_number (sizeof (struct Lisp_String)),
5637 make_number (total_free_strings)); 5657 bounded_number (total_strings),
5658 bounded_number (total_string_bytes),
5659 bounded_number (total_free_strings));
5660
5661 total[4] = list5 (Qvector, make_number (sizeof (struct Lisp_Vector)),
5662 bounded_number (total_vectors),
5663 bounded_number (total_vector_bytes),
5664 bounded_number (total_free_vector_bytes));
5665
5666 total[5] = list4 (Qfloat, make_number (sizeof (struct Lisp_Float)),
5667 bounded_number (total_floats),
5668 bounded_number (total_free_floats));
5669
5670 total[6] = list4 (Qinterval, make_number (sizeof (struct interval)),
5671 bounded_number (total_intervals),
5672 bounded_number (total_free_intervals));
5673
5674 total[7] = list3 (Qbuffer, make_number (sizeof (struct buffer)),
5675 bounded_number (total_buffers));
5638 5676
5639#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 5677#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
5640 { 5678 {
@@ -6535,6 +6573,7 @@ gc_sweep (void)
6535 { 6573 {
6536 register struct buffer *buffer = all_buffers, *prev = 0, *next; 6574 register struct buffer *buffer = all_buffers, *prev = 0, *next;
6537 6575
6576 total_buffers = 0;
6538 while (buffer) 6577 while (buffer)
6539 if (!VECTOR_MARKED_P (buffer)) 6578 if (!VECTOR_MARKED_P (buffer))
6540 { 6579 {
@@ -6550,6 +6589,7 @@ gc_sweep (void)
6550 { 6589 {
6551 VECTOR_UNMARK (buffer); 6590 VECTOR_UNMARK (buffer);
6552 UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer)); 6591 UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer));
6592 total_buffers++;
6553 prev = buffer, buffer = buffer->header.next.buffer; 6593 prev = buffer, buffer = buffer->header.next.buffer;
6554 } 6594 }
6555 } 6595 }
@@ -6592,22 +6632,17 @@ if heap statistics are not available. Both counters are in units of
6592 Lisp_Object val = Fmake_list (make_number (2), make_number (0)); 6632 Lisp_Object val = Fmake_list (make_number (2), make_number (0));
6593 6633
6594 XSETCAR (val, 6634 XSETCAR (val,
6595 (make_number 6635 bounded_number
6596 (min (MOST_POSITIVE_FIXNUM, 6636 ((total_free_conses * sizeof (struct Lisp_Cons)
6597 ((total_free_conses * sizeof (struct Lisp_Cons) 6637 + total_free_markers * sizeof (union Lisp_Misc)
6598 + total_free_markers * sizeof (union Lisp_Misc) 6638 + total_free_symbols * sizeof (struct Lisp_Symbol)
6599 + total_free_symbols * sizeof (struct Lisp_Symbol) 6639 + total_free_floats * sizeof (struct Lisp_Float)
6600 + total_free_floats * sizeof (struct Lisp_Float) 6640 + total_free_intervals * sizeof (struct interval)
6601 + total_free_intervals * sizeof (struct interval) 6641 + total_free_strings * sizeof (struct Lisp_String)
6602 + total_free_strings * sizeof (struct Lisp_String) 6642 + total_free_vector_bytes
6603 + total_free_vector_bytes 6643 + 1023) >> 10));
6604 + 1023)
6605 >> 10)))));
6606
6607#ifdef DOUG_LEA_MALLOC 6644#ifdef DOUG_LEA_MALLOC
6608 XSETCAR (XCDR (val), 6645 XSETCAR (XCDR (val), bounded_number ((mallinfo ().fordblks + 1023) >> 10));
6609 make_number (min (MOST_POSITIVE_FIXNUM,
6610 (mallinfo ().fordblks + 1023) >> 10)));
6611#endif 6646#endif
6612 return val; 6647 return val;
6613} 6648}
@@ -6629,14 +6664,14 @@ Frames, windows, buffers, and subprocesses count as vectors
6629{ 6664{
6630 Lisp_Object consed[8]; 6665 Lisp_Object consed[8];
6631 6666
6632 consed[0] = make_number (min (MOST_POSITIVE_FIXNUM, cons_cells_consed)); 6667 consed[0] = bounded_number (cons_cells_consed);
6633 consed[1] = make_number (min (MOST_POSITIVE_FIXNUM, floats_consed)); 6668 consed[1] = bounded_number (floats_consed);
6634 consed[2] = make_number (min (MOST_POSITIVE_FIXNUM, vector_cells_consed)); 6669 consed[2] = bounded_number (vector_cells_consed);
6635 consed[3] = make_number (min (MOST_POSITIVE_FIXNUM, symbols_consed)); 6670 consed[3] = bounded_number (symbols_consed);
6636 consed[4] = make_number (min (MOST_POSITIVE_FIXNUM, string_chars_consed)); 6671 consed[4] = bounded_number (string_chars_consed);
6637 consed[5] = make_number (min (MOST_POSITIVE_FIXNUM, misc_objects_consed)); 6672 consed[5] = bounded_number (misc_objects_consed);
6638 consed[6] = make_number (min (MOST_POSITIVE_FIXNUM, intervals_consed)); 6673 consed[6] = bounded_number (intervals_consed);
6639 consed[7] = make_number (min (MOST_POSITIVE_FIXNUM, strings_consed)); 6674 consed[7] = bounded_number (strings_consed);
6640 6675
6641 return Flist (8, consed); 6676 return Flist (8, consed);
6642} 6677}