unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: [Emacs-diffs] /srv/bzr/emacs/trunk r109111: Simple free memory accounting feature.
       [not found] <E1Sr227-00014W-5o@vcs.savannah.gnu.org>
@ 2012-07-17  9:45 ` Stefan Monnier
  2012-07-17 13:40   ` Dmitry Antipov
  0 siblings, 1 reply; 2+ messages in thread
From: Stefan Monnier @ 2012-07-17  9:45 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: emacs-devel

> -static EMACS_INT total_free_floats, total_floats;
> +static EMACS_INT total_free_floats, total_floats, total_free_vector_bytes;

Adding total_free_vector_bytes is a good change.
Similarly providing access to malloc's internal data is good, thanks.

> +DEFUN ("memory-free", Fmemory_free, Smemory_free, 0, 0, 0,
> +       doc: /* Return a list of two counters that measure how much free memory
> +is hold by the Emacs process.  Both counters are in KBytes.  First
> +counter shows how much memory holds in a free lists maintained by
> +the Emacs itself.  Second counter shows how much free memory is in
> +the heap (freed by Emacs but not released back to the operating
> +system).  If the second counter is zero, heap statistics is not
> +available.  Since both counters are updated after each garbage
> +collection, use (progn (garbage-collect) (memory-free)) to get 
> +accurate numbers.  */)

There are two problems, here:
- if the data is unavailable, better return nil than 0.
- we now have 2 ways to get the data, neither of which gives it all:
  garbage-collect returns details data but misses the new vector-bytes
  and bytes-free, whereas memory-free includes those 2 but only provides
  the combined value.

The first problem is obviously a detail, but the second problem needs to
be fixed.  The way I see it, it should be fixed by improving
garbage-collect's return value.  The only problem with that is backward
compatibility, but AFAIK there are only 2 users of that data:
memory-usage and chart.el, which we can both fix easily.
I suggest we make garbage-collect return its data in a new format
that is more self-descriptive, like an alist where each entry takes the
form (CATEGORY SIZE USED FREE), where CATEGORY would be a symbol (like
`cons') and SIZE is the size of each element in bytes.


        Stefan



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Emacs-diffs] /srv/bzr/emacs/trunk r109111: Simple free memory accounting feature.
  2012-07-17  9:45 ` [Emacs-diffs] /srv/bzr/emacs/trunk r109111: Simple free memory accounting feature Stefan Monnier
@ 2012-07-17 13:40   ` Dmitry Antipov
  0 siblings, 0 replies; 2+ messages in thread
From: Dmitry Antipov @ 2012-07-17 13:40 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

On 07/17/2012 01:45 PM, Stefan Monnier wrote:

> There are two problems, here:
> - if the data is unavailable, better return nil than 0.
> - we now have 2 ways to get the data, neither of which gives it all:
>    garbage-collect returns details data but misses the new vector-bytes
>    and bytes-free, whereas memory-free includes those 2 but only provides
>    the combined value.
>
> The first problem is obviously a detail, but the second problem needs to
> be fixed.  The way I see it, it should be fixed by improving
> garbage-collect's return value.  The only problem with that is backward
> compatibility, but AFAIK there are only 2 users of that data:
> memory-usage and chart.el, which we can both fix easily.
> I suggest we make garbage-collect return its data in a new format
> that is more self-descriptive, like an alist where each entry takes the
> form (CATEGORY SIZE USED FREE), where CATEGORY would be a symbol (like
> `cons') and SIZE is the size of each element in bytes.

OK, look at this.

Dmitry




[-- Attachment #2: gc.patch --]
[-- Type: text/plain, Size: 19938 bytes --]

=== modified file 'lisp/emacs-lisp/chart.el'
--- lisp/emacs-lisp/chart.el	2012-05-13 03:05:06 +0000
+++ lisp/emacs-lisp/chart.el	2012-07-17 13:00:22 +0000
@@ -676,23 +676,25 @@
   "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"

=== modified file 'src/alloc.c'
--- src/alloc.c	2012-07-17 12:31:29 +0000
+++ src/alloc.c	2012-07-17 13:37:24 +0000
@@ -187,11 +187,24 @@
 
 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_free_conses, total_free_markers, total_free_symbols;
-static EMACS_INT total_free_floats, total_floats, total_free_vector_bytes;
+/* Number of live and free objects of the particular type.  */
+
+static EMACS_INT total_conses, total_free_conses;
+static EMACS_INT total_symbols, total_free_symbols;
+static EMACS_INT total_miscs, total_free_miscs;
+static EMACS_INT total_intervals, total_free_intervals;
+static EMACS_INT total_floats, total_free_floats;
+static EMACS_INT total_buffers;
+
+/* Number of live strings, number of bytes
+   used by them, number of free strings.  */
+
+static EMACS_INT total_strings, total_string_bytes, total_free_strings;
+
+/* Number of live vectors, amount of bytes used by
+   them, number of free bytes in vector blocks.  */
+
+static EMACS_INT total_vectors, total_vector_bytes, total_free_vector_bytes;
 
 /* 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
@@ -1478,10 +1491,6 @@
 
 static int interval_block_index = INTERVAL_BLOCK_SIZE;
 
-/* Number of free and live intervals.  */
-
-static EMACS_INT total_free_intervals, total_intervals;
-
 /* List of free intervals.  */
 
 static INTERVAL interval_free_list;
@@ -1521,6 +1530,7 @@
 
   consing_since_gc += sizeof (struct interval);
   intervals_consed++;
+  total_intervals++;
   total_free_intervals--;
   RESET_INTERVAL (val);
   val->gcmarkbit = 0;
@@ -1702,14 +1712,6 @@
 
 static struct Lisp_String *string_free_list;
 
-/* Number of live and free Lisp_Strings.  */
-
-static EMACS_INT total_strings, total_free_strings;
-
-/* Number of bytes used by live strings.  */
-
-static EMACS_INT total_string_size;
-
 /* 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
    free-list.  */
@@ -1939,9 +1941,9 @@
 
   MALLOC_UNBLOCK_INPUT;
 
-  --total_free_strings;
-  ++total_strings;
-  ++strings_consed;
+  total_free_strings--;
+  total_strings++;
+  strings_consed++;
   consing_since_gc += sizeof *s;
 
 #ifdef GC_CHECK_STRING_BYTES
@@ -2067,6 +2069,7 @@
       old_data->string = NULL;
     }
 
+  total_string_bytes += needed;
   consing_since_gc += needed;
 }
 
@@ -2080,8 +2083,7 @@
   struct string_block *live_blocks = NULL;
 
   string_free_list = NULL;
-  total_strings = total_free_strings = 0;
-  total_string_size = 0;
+  total_strings = total_free_strings = total_string_bytes = 0;
 
   /* Scan strings_blocks, free Lisp_Strings that aren't marked.  */
   for (b = string_blocks; b; b = next)
@@ -2107,7 +2109,7 @@
 		    UNMARK_BALANCE_INTERVALS (s->intervals);
 
 		  ++total_strings;
-		  total_string_size += STRING_BYTES (s);
+		  total_string_bytes += STRING_BYTES (s);
 		}
 	      else
 		{
@@ -2636,6 +2638,7 @@
   eassert (!FLOAT_MARKED_P (XFLOAT (val)));
   consing_since_gc += sizeof (struct Lisp_Float);
   floats_consed++;
+  total_floats++;
   total_free_floats--;
   return val;
 }
@@ -2744,6 +2747,7 @@
   XSETCDR (val, cdr);
   eassert (!CONS_MARKED_P (XCONS (val)));
   consing_since_gc += sizeof (struct Lisp_Cons);
+  total_conses++;
   total_free_conses--;
   cons_cells_consed++;
   return val;
@@ -3069,6 +3073,14 @@
    ? vector->header.size & PSEUDOVECTOR_SIZE_MASK	\
    : vector->header.next.nbytes)
 
+/* Return the memory footprint of vector V in bytes.
+   Do not use for pseudovectors since the most of them
+   has something beyond Lisp objects at the beginning.  */
+
+#define VECTOR_BYTES(v)					\
+  (eassert (!((v)->header.size & PSEUDOVECTOR_FLAG)),	\
+   (header_size + VECTOR_SIZE (v) * word_size))
+
 /* Reclaim space used by unmarked vectors.  */
 
 static void
@@ -3077,7 +3089,7 @@
   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_free_vector_bytes = total_vector_bytes = 0;
   memset (vector_free_lists, 0, sizeof (vector_free_lists));
 
   /* Looking through vector blocks.  */
@@ -3092,7 +3104,8 @@
 	  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 +3161,10 @@
       if (VECTOR_MARKED_P (vector))
 	{
 	  VECTOR_UNMARK (vector);
-	  total_vector_size += VECTOR_SIZE (vector);
+	  total_vectors++;
+	  /* This code assumes that all pseudovectors are
+	     small enough to be allocated from blocks.  */
+	  total_vector_bytes += VECTOR_BYTES (vector);
 	  vprev = &vector->header.next.vector;
 	}
       else
@@ -3198,7 +3214,8 @@
       /* Back to a reasonable maximum of mmap'ed areas.  */
       mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
 #endif
-
+      total_vectors++;
+      total_vector_bytes += nbytes;
       consing_since_gc += nbytes;
       vector_cells_consed += len;
     }
@@ -3248,6 +3265,7 @@
 
   XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text)
 				     - header_size) / word_size);
+  total_buffers++;
   /* Note that the fields of B are not initialized.  */
   return b;
 }
@@ -3492,6 +3510,7 @@
   p->declared_special = 0;
   consing_since_gc += sizeof (struct Lisp_Symbol);
   symbols_consed++;
+  total_symbols++;
   total_free_symbols--;
   return val;
 }
@@ -3499,7 +3518,7 @@
 
 \f
 /***********************************************************************
-		       Marker (Misc) Allocation
+		       Misc Objects Allocation
  ***********************************************************************/
 
 /* Like union Lisp_Misc, but padded so that its size is a multiple of
@@ -3517,20 +3536,20 @@
 /* Allocation of markers and other objects that share that structure.
    Works like allocation of conses. */
 
-#define MARKER_BLOCK_SIZE \
-  ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc))
+#define MISC_BLOCK_SIZE \
+  ((1020 - sizeof (struct misc_block *)) / sizeof (union aligned_Lisp_Misc))
 
-struct marker_block
+struct misc_block
 {
-  /* Place `markers' first, to preserve alignment.  */
-  union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE];
-  struct marker_block *next;
+  /* Place `miscs' first, to preserve alignment.  */
+  union aligned_Lisp_Misc miscs[MISC_BLOCK_SIZE];
+  struct misc_block *next;
 };
 
-static struct marker_block *marker_block;
-static int marker_block_index = MARKER_BLOCK_SIZE;
+static struct misc_block *misc_block;
+static int misc_block_index = MISC_BLOCK_SIZE;
 
-static union Lisp_Misc *marker_free_list;
+static union Lisp_Misc *misc_free_list;
 
 /* Return a newly allocated Lisp_Misc object, with no substructure.  */
 
@@ -3543,28 +3562,29 @@
 
   MALLOC_BLOCK_INPUT;
 
-  if (marker_free_list)
+  if (misc_free_list)
     {
-      XSETMISC (val, marker_free_list);
-      marker_free_list = marker_free_list->u_free.chain;
+      XSETMISC (val, misc_free_list);
+      misc_free_list = misc_free_list->u_free.chain;
     }
   else
     {
-      if (marker_block_index == MARKER_BLOCK_SIZE)
+      if (misc_block_index == MISC_BLOCK_SIZE)
 	{
-	  struct marker_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC);
-	  new->next = marker_block;
-	  marker_block = new;
-	  marker_block_index = 0;
-	  total_free_markers += MARKER_BLOCK_SIZE;
+	  struct misc_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC);
+	  new->next = misc_block;
+	  misc_block = new;
+	  misc_block_index = 0;
+	  total_free_miscs += MISC_BLOCK_SIZE;
 	}
-      XSETMISC (val, &marker_block->markers[marker_block_index].m);
-      marker_block_index++;
+      XSETMISC (val, &misc_block->miscs[misc_block_index].m);
+      misc_block_index++;
     }
 
   MALLOC_UNBLOCK_INPUT;
 
-  --total_free_markers;
+  total_miscs++;
+  total_free_miscs--;
   consing_since_gc += sizeof (union Lisp_Misc);
   misc_objects_consed++;
   XMISCANY (val)->gcmarkbit = 0;
@@ -3577,10 +3597,9 @@
 free_misc (Lisp_Object misc)
 {
   XMISCTYPE (misc) = Lisp_Misc_Free;
-  XMISC (misc)->u_free.chain = marker_free_list;
-  marker_free_list = XMISC (misc);
-
-  total_free_markers++;
+  XMISC (misc)->u_free.chain = misc_free_list;
+  misc_free_list = XMISC (misc);
+  total_free_miscs++;
 }
 
 /* Return a Lisp_Misc_Save_Value object containing POINTER and
@@ -4309,17 +4328,17 @@
 {
   if (m->type == MEM_TYPE_MISC)
     {
-      struct marker_block *b = (struct marker_block *) m->start;
-      ptrdiff_t offset = (char *) p - (char *) &b->markers[0];
+      struct misc_block *b = (struct misc_block *) m->start;
+      ptrdiff_t offset = (char *) p - (char *) &b->miscs[0];
 
       /* P must point to the start of a Lisp_Misc, not be
 	 one of the unused cells in the current misc block,
 	 and not be on the free-list.  */
       return (offset >= 0
-	      && offset % sizeof b->markers[0] == 0
-	      && offset < (MARKER_BLOCK_SIZE * sizeof b->markers[0])
-	      && (b != marker_block
-		  || offset / sizeof b->markers[0] < marker_block_index)
+	      && offset % sizeof b->miscs[0] == 0
+	      && offset < (MISC_BLOCK_SIZE * sizeof b->miscs[0])
+	      && (b != misc_block
+		  || offset / sizeof b->miscs[0] < misc_block_index)
 	      && ((union Lisp_Misc *) p)->u_any.type != Lisp_Misc_Free);
     }
   else
@@ -5345,10 +5364,14 @@
 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'.  */)
@@ -5594,9 +5617,9 @@
 
       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_miscs * sizeof (union Lisp_Misc);
+      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 +5644,38 @@
 
   unbind_to (count, Qnil);
 
-  total[0] = Fcons (make_number (total_conses),
+  total[0] = list4 (Qcons, make_number (sizeof (struct Lisp_Cons)),
+		    make_number (total_conses),
 		    make_number (total_free_conses));
-  total[1] = Fcons (make_number (total_symbols),
+
+  total[1] = list4 (Qsymbol, make_number (sizeof (struct Lisp_Symbol)),
+		    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),
+
+  total[2] = list4 (Qmisc, make_number (sizeof (union Lisp_Misc)),
+		    make_number (total_miscs),
+		    make_number (total_free_miscs));
+
+  total[3] = list5 (Qstring, make_number (sizeof (struct Lisp_String)),
+		    make_number (total_strings),
+		    make_number (total_string_bytes),
+		    make_number (total_free_strings));
+
+  total[4] = list5 (Qvector, make_number (sizeof (struct Lisp_Vector)),
+		    make_number (total_vectors),
+		    make_number (total_vector_bytes),
+		    make_number (total_free_vector_bytes));
+
+  total[5] = list4 (Qfloat, make_number (sizeof (struct Lisp_Float)),
+		    make_number (total_floats),
 		    make_number (total_free_floats));
-  total[6] = Fcons (make_number (total_intervals),
+
+  total[6] = list4 (Qinterval, make_number (sizeof (struct interval)),
+		    make_number (total_intervals),
 		    make_number (total_free_intervals));
-  total[7] = Fcons (make_number (total_strings),
-		    make_number (total_free_strings));
+
+  total[7] = list3 (Qbuffer, make_number (sizeof (struct buffer)),
+		    make_number (total_buffers));
 
 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
   {
@@ -6477,47 +6518,47 @@
   /* Put all unmarked misc's on free list.
      For a marker, first unchain it from the buffer it points into.  */
   {
-    register struct marker_block *mblk;
-    struct marker_block **mprev = &marker_block;
-    register int lim = marker_block_index;
+    register struct misc_block *mblk;
+    struct misc_block **mprev = &misc_block;
+    register int lim = misc_block_index;
     EMACS_INT num_free = 0, num_used = 0;
 
-    marker_free_list = 0;
+    misc_free_list = 0;
 
-    for (mblk = marker_block; mblk; mblk = *mprev)
+    for (mblk = misc_block; mblk; mblk = *mprev)
       {
 	register int i;
 	int this_free = 0;
 
 	for (i = 0; i < lim; i++)
 	  {
-	    if (!mblk->markers[i].m.u_any.gcmarkbit)
+	    if (!mblk->miscs[i].m.u_any.gcmarkbit)
 	      {
-		if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
-		  unchain_marker (&mblk->markers[i].m.u_marker);
+		if (mblk->miscs[i].m.u_any.type == Lisp_Misc_Marker)
+		  unchain_marker (&mblk->miscs[i].m.u_marker);
 		/* Set the type of the freed object to Lisp_Misc_Free.
 		   We could leave the type alone, since nobody checks it,
 		   but this might catch bugs faster.  */
-		mblk->markers[i].m.u_marker.type = Lisp_Misc_Free;
-		mblk->markers[i].m.u_free.chain = marker_free_list;
-		marker_free_list = &mblk->markers[i].m;
+		mblk->miscs[i].m.u_marker.type = Lisp_Misc_Free;
+		mblk->miscs[i].m.u_free.chain = misc_free_list;
+		misc_free_list = &mblk->miscs[i].m;
 		this_free++;
 	      }
 	    else
 	      {
 		num_used++;
-		mblk->markers[i].m.u_any.gcmarkbit = 0;
+		mblk->miscs[i].m.u_any.gcmarkbit = 0;
 	      }
 	  }
-	lim = MARKER_BLOCK_SIZE;
+	lim = MISC_BLOCK_SIZE;
 	/* If this block contains only free markers and we have already
 	   seen more than two blocks worth of free markers then deallocate
 	   this block.  */
-	if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE)
+	if (this_free == MISC_BLOCK_SIZE && num_free > MISC_BLOCK_SIZE)
 	  {
 	    *mprev = mblk->next;
 	    /* Unhook from the free list.  */
-	    marker_free_list = mblk->markers[0].m.u_free.chain;
+	    misc_free_list = mblk->miscs[0].m.u_free.chain;
 	    lisp_free (mblk);
 	  }
 	else
@@ -6527,14 +6568,15 @@
 	  }
       }
 
-    total_markers = num_used;
-    total_free_markers = num_free;
+    total_miscs = num_used;
+    total_free_miscs = num_free;
   }
 
   /* Free all unmarked buffers */
   {
     register struct buffer *buffer = all_buffers, *prev = 0, *next;
 
+    total_buffers = 0;
     while (buffer)
       if (!VECTOR_MARKED_P (buffer))
 	{
@@ -6548,6 +6590,7 @@
 	}
       else
 	{
+	  total_buffers++;
 	  VECTOR_UNMARK (buffer);
 	  UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer));
 	  prev = buffer, buffer = buffer->header.next.buffer;
@@ -6595,7 +6638,7 @@
   data[0] = make_number
     (min (MOST_POSITIVE_FIXNUM,
 	  (total_free_conses * sizeof (struct Lisp_Cons)
-	   + total_free_markers * sizeof (union Lisp_Misc)
+	   + total_free_miscs * sizeof (union Lisp_Misc)
 	   + total_free_symbols * sizeof (struct Lisp_Symbol)
 	   + total_free_floats * sizeof (struct Lisp_Float)
 	   + total_free_intervals * sizeof (struct interval)
@@ -6605,7 +6648,7 @@
   data[1] = make_number
     (min (MOST_POSITIVE_FIXNUM, mallinfo ().fordblks / 1024));
 #else
-  data[1] = make_number (0);
+  data[1] = Qnil;
 #endif
   return Flist (2, data);
 }

=== modified file 'src/data.c'
--- src/data.c	2012-07-10 08:43:46 +0000
+++ src/data.c	2012-07-17 12:36:31 +0000
@@ -83,12 +83,12 @@
 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, Qmarker, Qmisc;
 Lisp_Object Qwindow;
-static Lisp_Object Qfloat, Qwindow_configuration;
+static Lisp_Object Qoverlay, Qwindow_configuration;
 static Lisp_Object Qprocess;
-static Lisp_Object Qcompiled_function, Qframe, Qvector;
+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 @@
   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 @@
   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");
 

=== modified file 'src/lisp.h'
--- src/lisp.h	2012-07-16 04:47:31 +0000
+++ src/lisp.h	2012-07-17 12:36:31 +0000
@@ -2332,7 +2332,8 @@
 extern Lisp_Object Qfloatp;
 extern Lisp_Object Qnumberp, Qnumber_or_marker_p;
 
-extern Lisp_Object Qinteger;
+extern Lisp_Object Qinteger, Qcons, Qsymbol, Qmarker, Qstring;
+extern Lisp_Object Qmisc, Qvector, Qfloat, Qinterval, Qbuffer;
 
 extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-07-17 13:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <E1Sr227-00014W-5o@vcs.savannah.gnu.org>
2012-07-17  9:45 ` [Emacs-diffs] /srv/bzr/emacs/trunk r109111: Simple free memory accounting feature Stefan Monnier
2012-07-17 13:40   ` Dmitry Antipov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).