Commit 3ab6e069 authored by Dmitry Antipov's avatar Dmitry Antipov

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.
parent 0a60bc10
2012-07-18 Dmitry Antipov <dmantipov@yandex.ru>
Reflect recent changes in Fgarbage_collect.
* emacs-lisp/chart.el (chart-emacs-storage): Change to
reflect new format of data returned by Fgarbage_collect.
2012-07-17 Fabián Ezequiel Gallina <fgallina@cuca>
New utility functions + python-info-ppss-context fix (Bug#11910).
......
......@@ -676,23 +676,25 @@ SORT-PRED if desired."
"Chart the current storage requirements of Emacs."
(interactive)
(let* ((data (garbage-collect))
(names '("strings/2" "vectors"
"conses" "free cons"
"syms" "free syms"
"markers" "free mark"
;; "floats" "free flt"
))
(nums (list (/ (nth 3 data) 2)
(nth 4 data)
(car (car data)) ; conses
(cdr (car data))
(car (nth 1 data)) ; syms
(cdr (nth 1 data))
(car (nth 2 data)) ; markers
(cdr (nth 2 data))
;(car (nth 5 data)) ; floats are Emacs only
;(cdr (nth 5 data))
)))
(cons-info (nth 0 data))
(symbol-info (nth 1 data))
(misc-info (nth 2 data))
(string-info (nth 3 data))
(vector-info (nth 4 data))
(float-info (nth 5 data))
(interval-info (nth 6 data))
(buffer-info (nth 7 data))
(names '("conses" "symbols" "miscs" "strings"
"vectors" "floats" "intervals" "buffers"))
(nums (list (* (nth 1 cons-info) (nth 2 cons-info))
(* (nth 1 symbol-info) (nth 2 symbol-info))
(* (nth 1 misc-info) (nth 2 misc-info))
(+ (* (nth 1 string-info) (nth 2 string-info))
(nth 3 string-info))
(nth 3 vector-info)
(* (nth 1 float-info) (nth 2 float-info))
(* (nth 1 interval-info) (nth 2 interval-info))
(* (nth 1 buffer-info) (nth 2 buffer-info)))))
;; Let's create the chart!
(chart-bar-quickie 'vertical "Emacs Runtime Storage Usage"
names "Storage Items"
......
2012-07-18 Dmitry Antipov <dmantipov@yandex.ru>
Return more descriptive data from Fgarbage_collect.
Suggested by Stefan Monnier in
http://lists.gnu.org/archive/html/emacs-devel/2012-07/msg00369.html.
* 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.
* data.c (Qfloat, Qvector, Qsymbol, Qstring, Qcons): Make global.
(Qinterval, Qmisc): New symbols.
(syms_of_data): Initialize them.
* lisp.h (Qinterval, Qsymbol, Qstring, Qmisc, Qvector, Qfloat)
(Qcons, Qbuffer): New declarations.
2012-07-17 Paul Eggert <eggert@cs.ucla.edu>
* alloc.c (Fmemory_free): Account for memory-free's own storage.
......
......@@ -189,9 +189,9 @@ int abort_on_gc;
/* Number of live and free conses etc. */
static EMACS_INT total_conses, total_markers, total_symbols, total_vector_size;
static EMACS_INT total_conses, total_markers, total_symbols, total_buffers;
static EMACS_INT total_free_conses, total_free_markers, total_free_symbols;
static EMACS_INT total_free_floats, total_floats, total_free_vector_bytes;
static EMACS_INT total_free_floats, total_floats;
/* Points to memory space allocated as "spare", to be freed if we run
out of memory. We keep one large block, four cons-blocks, and
......@@ -1708,7 +1708,7 @@ static EMACS_INT total_strings, total_free_strings;
/* Number of bytes used by live strings. */
static EMACS_INT total_string_size;
static EMACS_INT total_string_bytes;
/* Given a pointer to a Lisp_String S which is on the free-list
string_free_list, return a pointer to its successor in the
......@@ -2081,7 +2081,7 @@ sweep_strings (void)
string_free_list = NULL;
total_strings = total_free_strings = 0;
total_string_size = 0;
total_string_bytes = 0;
/* Scan strings_blocks, free Lisp_Strings that aren't marked. */
for (b = string_blocks; b; b = next)
......@@ -2107,7 +2107,7 @@ sweep_strings (void)
UNMARK_BALANCE_INTERVALS (s->intervals);
++total_strings;
total_string_size += STRING_BYTES (s);
total_string_bytes += STRING_BYTES (s);
}
else
{
......@@ -2957,6 +2957,14 @@ static struct Lisp_Vector *large_vectors;
Lisp_Object zero_vector;
/* Number of live vectors. */
static EMACS_INT total_vectors;
/* Number of bytes used by live and free vectors. */
static EMACS_INT total_vector_bytes, total_free_vector_bytes;
/* Get a new vector block. */
static struct vector_block *
......@@ -3047,12 +3055,6 @@ allocate_vector_from_block (size_t nbytes)
return vector;
}
/* Return how many Lisp_Objects can be stored in V. */
#define VECTOR_SIZE(v) ((v)->header.size & PSEUDOVECTOR_FLAG ? \
(PSEUDOVECTOR_SIZE_MASK & (v)->header.size) : \
(v)->header.size)
/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
#define VECTOR_IN_BLOCK(vector, block) \
......@@ -3077,7 +3079,7 @@ sweep_vectors (void)
struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
struct Lisp_Vector *vector, *next, **vprev = &large_vectors;
total_free_vector_bytes = total_vector_size = 0;
total_vectors = total_vector_bytes = total_free_vector_bytes = 0;
memset (vector_free_lists, 0, sizeof (vector_free_lists));
/* Looking through vector blocks. */
......@@ -3092,7 +3094,8 @@ sweep_vectors (void)
if (VECTOR_MARKED_P (vector))
{
VECTOR_UNMARK (vector);
total_vector_size += VECTOR_SIZE (vector);
total_vectors++;
total_vector_bytes += vector->header.next.nbytes;
next = ADVANCE (vector, vector->header.next.nbytes);
}
else
......@@ -3148,7 +3151,12 @@ sweep_vectors (void)
if (VECTOR_MARKED_P (vector))
{
VECTOR_UNMARK (vector);
total_vector_size += VECTOR_SIZE (vector);
total_vectors++;
/* All pseudovectors are small enough to be allocated from
vector blocks. This code should be redesigned if some
pseudovector type grows beyond VBLOCK_BYTES_MAX. */
eassert (!(vector->header.size & PSEUDOVECTOR_FLAG));
total_vector_bytes += header_size + vector->header.size * word_size;
vprev = &vector->header.next.vector;
}
else
......@@ -5339,16 +5347,28 @@ inhibit_garbage_collection (void)
return count;
}
/* Used to avoid possible overflows when
converting from C to Lisp integers. */
static inline Lisp_Object
bounded_number (EMACS_INT number)
{
return make_number (min (MOST_POSITIVE_FIXNUM, number));
}
DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
doc: /* Reclaim storage for Lisp objects no longer needed.
Garbage collection happens automatically if you cons more than
`gc-cons-threshold' bytes of Lisp data since previous garbage collection.
`garbage-collect' normally returns a list with info on amount of space in use:
((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)
(USED-MISCS . FREE-MISCS) USED-STRING-CHARS USED-VECTOR-SLOTS
(USED-FLOATS . FREE-FLOATS) (USED-INTERVALS . FREE-INTERVALS)
(USED-STRINGS . FREE-STRINGS))
((CONS INTERNAL-SIZE USED-CONSES FREE-CONSES)
(SYMBOL INTERNAL-SIZE USED-SYMBOLS FREE-SYMBOLS)
(MISC INTERNAL-SIZE USED-MISCS FREE-MISCS)
(STRING INTERNAL-SIZE USED-STRINGS USED-STRING-BYTES FREE-STRING)
(VECTOR INTERNAL-SIZE USED-VECTORS USED-VECTOR-BYTES FREE-VECTOR-BYTES)
(FLOAT INTERNAL-SIZE USED-FLOATS FREE-FLOATS)
(INTERVAL INTERNAL-SIZE USED-INTERVALS FREE-INTERVALS)
(BUFFER INTERNAL-SIZE USED-BUFFERS))
However, if there was overflow in pure space, `garbage-collect'
returns nil, because real GC can't be done.
See Info node `(elisp)Garbage Collection'. */)
......@@ -5595,8 +5615,8 @@ See Info node `(elisp)Garbage Collection'. */)
tot += total_conses * sizeof (struct Lisp_Cons);
tot += total_symbols * sizeof (struct Lisp_Symbol);
tot += total_markers * sizeof (union Lisp_Misc);
tot += total_string_size;
tot += total_vector_size * sizeof (Lisp_Object);
tot += total_string_bytes;
tot += total_vector_bytes;
tot += total_floats * sizeof (struct Lisp_Float);
tot += total_intervals * sizeof (struct interval);
tot += total_strings * sizeof (struct Lisp_String);
......@@ -5621,20 +5641,38 @@ See Info node `(elisp)Garbage Collection'. */)
unbind_to (count, Qnil);
total[0] = Fcons (make_number (total_conses),
make_number (total_free_conses));
total[1] = Fcons (make_number (total_symbols),
make_number (total_free_symbols));
total[2] = Fcons (make_number (total_markers),
make_number (total_free_markers));
total[3] = make_number (total_string_size);
total[4] = make_number (total_vector_size);
total[5] = Fcons (make_number (total_floats),
make_number (total_free_floats));
total[6] = Fcons (make_number (total_intervals),
make_number (total_free_intervals));
total[7] = Fcons (make_number (total_strings),
make_number (total_free_strings));
total[0] = list4 (Qcons, make_number (sizeof (struct Lisp_Cons)),
bounded_number (total_conses),
bounded_number (total_free_conses));
total[1] = list4 (Qsymbol, make_number (sizeof (struct Lisp_Symbol)),
bounded_number (total_symbols),
bounded_number (total_free_symbols));
total[2] = list4 (Qmisc, make_number (sizeof (union Lisp_Misc)),
bounded_number (total_markers),
bounded_number (total_free_markers));
total[3] = list5 (Qstring, make_number (sizeof (struct Lisp_String)),
bounded_number (total_strings),
bounded_number (total_string_bytes),
bounded_number (total_free_strings));
total[4] = list5 (Qvector, make_number (sizeof (struct Lisp_Vector)),
bounded_number (total_vectors),
bounded_number (total_vector_bytes),
bounded_number (total_free_vector_bytes));
total[5] = list4 (Qfloat, make_number (sizeof (struct Lisp_Float)),
bounded_number (total_floats),
bounded_number (total_free_floats));
total[6] = list4 (Qinterval, make_number (sizeof (struct interval)),
bounded_number (total_intervals),
bounded_number (total_free_intervals));
total[7] = list3 (Qbuffer, make_number (sizeof (struct buffer)),
bounded_number (total_buffers));
#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
{
......@@ -6535,6 +6573,7 @@ gc_sweep (void)
{
register struct buffer *buffer = all_buffers, *prev = 0, *next;
total_buffers = 0;
while (buffer)
if (!VECTOR_MARKED_P (buffer))
{
......@@ -6550,6 +6589,7 @@ gc_sweep (void)
{
VECTOR_UNMARK (buffer);
UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer));
total_buffers++;
prev = buffer, buffer = buffer->header.next.buffer;
}
}
......@@ -6592,22 +6632,17 @@ if heap statistics are not available. Both counters are in units of
Lisp_Object val = Fmake_list (make_number (2), make_number (0));
XSETCAR (val,
(make_number
(min (MOST_POSITIVE_FIXNUM,
((total_free_conses * sizeof (struct Lisp_Cons)
+ total_free_markers * sizeof (union Lisp_Misc)
+ total_free_symbols * sizeof (struct Lisp_Symbol)
+ total_free_floats * sizeof (struct Lisp_Float)
+ total_free_intervals * sizeof (struct interval)
+ total_free_strings * sizeof (struct Lisp_String)
+ total_free_vector_bytes
+ 1023)
>> 10)))));
bounded_number
((total_free_conses * sizeof (struct Lisp_Cons)
+ total_free_markers * sizeof (union Lisp_Misc)
+ total_free_symbols * sizeof (struct Lisp_Symbol)
+ total_free_floats * sizeof (struct Lisp_Float)
+ total_free_intervals * sizeof (struct interval)
+ total_free_strings * sizeof (struct Lisp_String)
+ total_free_vector_bytes
+ 1023) >> 10));
#ifdef DOUG_LEA_MALLOC
XSETCAR (XCDR (val),
make_number (min (MOST_POSITIVE_FIXNUM,
(mallinfo ().fordblks + 1023) >> 10)));
XSETCAR (XCDR (val), bounded_number ((mallinfo ().fordblks + 1023) >> 10));
#endif
return val;
}
......@@ -6629,14 +6664,14 @@ Frames, windows, buffers, and subprocesses count as vectors
{
Lisp_Object consed[8];
consed[0] = make_number (min (MOST_POSITIVE_FIXNUM, cons_cells_consed));
consed[1] = make_number (min (MOST_POSITIVE_FIXNUM, floats_consed));
consed[2] = make_number (min (MOST_POSITIVE_FIXNUM, vector_cells_consed));
consed[3] = make_number (min (MOST_POSITIVE_FIXNUM, symbols_consed));
consed[4] = make_number (min (MOST_POSITIVE_FIXNUM, string_chars_consed));
consed[5] = make_number (min (MOST_POSITIVE_FIXNUM, misc_objects_consed));
consed[6] = make_number (min (MOST_POSITIVE_FIXNUM, intervals_consed));
consed[7] = make_number (min (MOST_POSITIVE_FIXNUM, strings_consed));
consed[0] = bounded_number (cons_cells_consed);
consed[1] = bounded_number (floats_consed);
consed[2] = bounded_number (vector_cells_consed);
consed[3] = bounded_number (symbols_consed);
consed[4] = bounded_number (string_chars_consed);
consed[5] = bounded_number (misc_objects_consed);
consed[6] = bounded_number (intervals_consed);
consed[7] = bounded_number (strings_consed);
return Flist (8, consed);
}
......
......@@ -83,12 +83,12 @@ Lisp_Object Qoverflow_error, Qunderflow_error;
Lisp_Object Qfloatp;
Lisp_Object Qnumberp, Qnumber_or_marker_p;
Lisp_Object Qinteger;
static Lisp_Object Qsymbol, Qstring, Qcons, Qmarker, Qoverlay;
Lisp_Object Qinteger, Qinterval, Qfloat, Qvector;
Lisp_Object Qsymbol, Qstring, Qcons, Qmisc;
Lisp_Object Qwindow;
static Lisp_Object Qfloat, Qwindow_configuration;
static Lisp_Object Qprocess;
static Lisp_Object Qcompiled_function, Qframe, Qvector;
static Lisp_Object Qoverlay, Qwindow_configuration;
static Lisp_Object Qprocess, Qmarker;
static Lisp_Object Qcompiled_function, Qframe;
Lisp_Object Qbuffer;
static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
static Lisp_Object Qsubrp, Qmany, Qunevalled;
......@@ -3083,7 +3083,6 @@ syms_of_data (void)
DEFSYM (Qwindow_configuration, "window-configuration");
DEFSYM (Qprocess, "process");
DEFSYM (Qwindow, "window");
/* DEFSYM (Qsubr, "subr"); */
DEFSYM (Qcompiled_function, "compiled-function");
DEFSYM (Qbuffer, "buffer");
DEFSYM (Qframe, "frame");
......@@ -3091,6 +3090,9 @@ syms_of_data (void)
DEFSYM (Qchar_table, "char-table");
DEFSYM (Qbool_vector, "bool-vector");
DEFSYM (Qhash_table, "hash-table");
/* Used by Fgarbage_collect. */
DEFSYM (Qinterval, "interval");
DEFSYM (Qmisc, "misc");
DEFSYM (Qdefun, "defun");
......
......@@ -2332,7 +2332,8 @@ extern Lisp_Object Qoverflow_error, Qunderflow_error;
extern Lisp_Object Qfloatp;
extern Lisp_Object Qnumberp, Qnumber_or_marker_p;
extern Lisp_Object Qinteger;
extern Lisp_Object Qinteger, Qinterval, Qsymbol, Qstring;
extern Lisp_Object Qmisc, Qvector, Qfloat, Qcons, Qbuffer;
extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment