emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GC


From: Stefan Monnier
Subject: Re: GC
Date: Mon, 11 Jul 2005 13:00:34 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

>>>>> "Richard" == Richard M Stallman <address@hidden> writes:

>     I'd had already suggested a change to grow gc-cons-threshold as the heap
>     grows (a long time ago), and I see that XEmacs's gc-cons-percentage is
>     clean interface to such a feature.  I think we should introduce this
>     variable and give it a good non-zero default value.

> I agree.  Would you like to do it?

How 'bout the patch below.
It sets the default value to 0.1 (i.e. 10%), which means that the current
400KB threshold (on 32 bit systems) is used until the heap grows to 4MB.
A 4MB heap is not enormous, but it's not small either (my one week old
running Emacs process with 14 frames and 30 buffers has a heap of about
6MB).  This notion of "heap size" is not exactly what you'd expect (it
ignores buffers and a few other such things) but it reflects fairly well the
part of the heap that the GC actually cares about.


        Stefan


--- orig/src/alloc.c
+++ mod/src/alloc.c
@@ -180,6 +180,8 @@
 /* Number of bytes of consing since GC before another GC should be done. */
 
 EMACS_INT gc_cons_threshold;
+static EMACS_INT gc_cons_min_threshold;
+static Lisp_Object Vgc_cons_percentage;
 
 /* Nonzero during GC.  */
 
@@ -4966,8 +4968,29 @@
   gc_in_progress = 0;
 
   consing_since_gc = 0;
-  if (gc_cons_threshold < 10000)
-    gc_cons_threshold = 10000;
+  if (gc_cons_min_threshold < 10000)
+    gc_cons_min_threshold = 10000;
+
+  gc_cons_threshold = gc_cons_min_threshold;
+
+  if (FLOATP (Vgc_cons_percentage))
+    { /* Set gc_cons_threshold.  */
+      EMACS_INT total = 0;
+      EMACS_INT threshold;
+      total += total_conses  * sizeof (struct Lisp_Cons);
+      total += total_symbols * sizeof (struct Lisp_Symbol);
+      total += total_markers * sizeof (union Lisp_Misc);
+      total += total_string_size;
+      total += total_vectors * sizeof (struct Lisp_Vector);
+      total += total_vector_size * sizeof (Lisp_Object);
+      total += total_floats  * sizeof (struct Lisp_Float);
+      total += total_intervals * sizeof (struct interval);
+      total += total_strings * sizeof (struct Lisp_String);
+      
+      threshold = total * XFLOAT_DATA (Vgc_cons_percentage);
+      if (threshold > gc_cons_threshold)
+       gc_cons_threshold = threshold;
+    }
 
   if (garbage_collection_messages)
     {
@@ -6087,7 +6110,7 @@
   byte_stack_list = 0;
   staticidx = 0;
   consing_since_gc = 0;
-  gc_cons_threshold = 100000 * sizeof (Lisp_Object);
+  gc_cons_min_threshold = 100000 * sizeof (Lisp_Object);
 #ifdef VIRT_ADDR_VARIES
   malloc_sbrk_unused = 1<<22;  /* A large number */
   malloc_sbrk_used = 100000;   /* as reasonable as any number */
@@ -6124,7 +6147,7 @@
 void
 syms_of_alloc ()
 {
-  DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold,
+  DEFVAR_INT ("gc-cons-threshold", &gc_cons_min_threshold,
              doc: /* *Number of bytes of consing between garbage collections.
 Garbage collection can happen automatically once this many bytes have been
 allocated since the last garbage collection.  All data types count.
@@ -6132,7 +6155,15 @@
 Garbage collection happens automatically only when `eval' is called.
 
 By binding this temporarily to a large number, you can effectively
-prevent garbage collection during a part of the program.  */);
+prevent garbage collection during a part of the program.
+See also `gc-cons-percentage'.  */);
+
+  DEFVAR_LISP ("gc-cons-percentage", &Vgc_cons_percentage,
+              doc: /* *Portion of the heap used for allocation.
+Garbage collection can happen automatically once this portion of the heap
+has been allocated since the last garbage collection.
+If this portion is smaller than `gc-cons-threshold', this is ignored.  */);
+  Vgc_cons_percentage = make_float (0.1);
 
   DEFVAR_INT ("pure-bytes-used", &pure_bytes_used,
              doc: /* Number of bytes of sharable Lisp data allocated so far.  
*/);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]