]> code.delx.au - gnu-emacs/blobdiff - src/alloc.c
(font-lock-syntactic-keywords): Add defvar.
[gnu-emacs] / src / alloc.c
index 143f5c76292ead84560b7e96a4fd184929df80c3..3c9b2199e5239e2eb1348316a3c6fb8db67309be 100644 (file)
@@ -1,6 +1,6 @@
 /* Storage allocation and gc for GNU Emacs Lisp interpreter.
    Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
-      2000, 2001, 2002, 2003, 2004  Free Software Foundation, Inc.
+      2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -103,7 +103,7 @@ extern __malloc_size_t __malloc_extra_blocks;
    that the backend handles concurrent access to malloc within its own threads
    but Emacs code running in the main thread is not included in that control).
 
-   When UNBLOCK_INPUT is called, revoke_input_signal may be called.  If this
+   When UNBLOCK_INPUT is called, reinvoke_input_signal may be called.  If this
    happens in one of the backend threads we will have two threads that tries
    to run Emacs code at once, and the code is not prepared for that.
    To prevent that, we only call BLOCK/UNBLOCK from the main thread.  */
@@ -143,11 +143,11 @@ static __malloc_size_t bytes_used_when_full;
 
 #define MARK_STRING(S)         ((S)->size |= ARRAY_MARK_FLAG)
 #define UNMARK_STRING(S)       ((S)->size &= ~ARRAY_MARK_FLAG)
-#define STRING_MARKED_P(S)     ((S)->size & ARRAY_MARK_FLAG)
+#define STRING_MARKED_P(S)     (((S)->size & ARRAY_MARK_FLAG) != 0)
 
 #define VECTOR_MARK(V)         ((V)->size |= ARRAY_MARK_FLAG)
 #define VECTOR_UNMARK(V)       ((V)->size &= ~ARRAY_MARK_FLAG)
-#define VECTOR_MARKED_P(V)     ((V)->size & ARRAY_MARK_FLAG)
+#define VECTOR_MARKED_P(V)     (((V)->size & ARRAY_MARK_FLAG) != 0)
 
 /* Value is the number of bytes/chars of S, a pointer to a struct
    Lisp_String.  This must be used instead of STRING_BYTES (S) or
@@ -172,10 +172,16 @@ EMACS_INT misc_objects_consed;
 EMACS_INT intervals_consed;
 EMACS_INT strings_consed;
 
-/* Number of bytes of consing since GC before another GC should be done. */
+/* Minimum number of bytes of consing since GC before next GC. */
 
 EMACS_INT gc_cons_threshold;
 
+/* Similar minimum, computed from Vgc_cons_percentage.  */
+
+EMACS_INT gc_relative_threshold;
+
+static Lisp_Object Vgc_cons_percentage;
+
 /* Nonzero during GC.  */
 
 int gc_in_progress;
@@ -309,6 +315,7 @@ static void mark_glyph_matrix P_ ((struct glyph_matrix *));
 static void mark_face_cache P_ ((struct face_cache *));
 
 #ifdef HAVE_WINDOW_SYSTEM
+extern void mark_fringe_data P_ ((void));
 static void mark_image P_ ((struct image *));
 static void mark_image_cache P_ ((struct frame *));
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -533,6 +540,12 @@ memory_full ()
     Fsignal (Qnil, Vmemory_signal_data);
 }
 
+DEFUN ("memory-full-p", Fmemory_full_p, Smemory_full_p, 0, 0, 0,
+       doc: /* t if memory is nearly full, nil otherwise.  */)
+  ()
+{
+  return (spare_memory ? Qnil : Qt);
+}
 
 /* Called if we can't allocate relocatable space for a buffer.  */
 
@@ -601,22 +614,24 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
           ((unsigned)(ptr[-4]) << 24))
 
 
-/* The call depth in overrun_check  functions.  Realloc may call both malloc
-   and free.  If realloc calls malloc, this may happen:
-   overrun_check_realloc()
-      -> malloc -> (via hook)_-> emacs_blocked_malloc
-         -> overrun_check_malloc
-            call malloc  (hooks are NULL, so real malloc is called).
-            malloc returns 10000.
-            add overhead, return 10016.
-      <- (back in overrun_check_realloc)
+/* The call depth in overrun_check functions.  For example, this might happen:
+   xmalloc()
+     overrun_check_malloc()
+       -> malloc -> (via hook)_-> emacs_blocked_malloc
+          -> overrun_check_malloc
+             call malloc  (hooks are NULL, so real malloc is called).
+             malloc returns 10000.
+             add overhead, return 10016.
+      <- (back in overrun_check_malloc)
       add overhead again, return 10032
+   xmalloc returns 10032.
 
    (time passes).
 
-   overrun_check_free(10032)
-     decrease overhed
-     free(10016)  <-  crash, because 10000 is the original pointer.  */
+   xfree(10032)
+     overrun_check_free(10032)
+       decrease overhed
+       free(10016)  <-  crash, because 10000 is the original pointer.  */
 
 static int check_depth;
 
@@ -702,9 +717,14 @@ overrun_check_free (block)
                val + osize,
                XMALLOC_OVERRUN_CHECK_SIZE))
        abort ();
+#ifdef XMALLOC_CLEAR_FREE_MEMORY
+      val -= XMALLOC_OVERRUN_CHECK_SIZE;
+      memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_SIZE*2);
+#else
       bzero (val + osize, XMALLOC_OVERRUN_CHECK_SIZE);
       val -= XMALLOC_OVERRUN_CHECK_SIZE;
       bzero (val, XMALLOC_OVERRUN_CHECK_SIZE);
+#endif
     }
 
   free (val);
@@ -882,12 +902,13 @@ lisp_free (block)
    On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
    posix_memalign on the other hand would ideally prefer a value of 4
    because otherwise, there's 1020 bytes wasted between each ablocks.
-   But testing shows that those 1020 will most of the time be efficiently
-   used by malloc to place other objects, so a value of 0 is still preferable
-   unless you have a lot of cons&floats and virtually nothing else.  */
+   In Emacs, testing shows that those 1020 can most of the time be
+   efficiently used by malloc to place other objects, so a value of 0 can
+   still preferable unless you have a lot of aligned blocks and virtually
+   nothing else.  */
 #define BLOCK_PADDING 0
 #define BLOCK_BYTES \
-  (BLOCK_ALIGN - sizeof (struct aligned_block *) - BLOCK_PADDING)
+  (BLOCK_ALIGN - sizeof (struct ablock *) - BLOCK_PADDING)
 
 /* Internal data structures and constants.  */
 
@@ -1110,18 +1131,35 @@ allocate_buffer ()
   return b;
 }
 
+\f
+#ifndef SYSTEM_MALLOC
+
+/* If we released our reserve (due to running out of memory),
+   and we have a fair amount free once again,
+   try to set aside another reserve in case we run out once more.
+
+   This is called when a relocatable block is freed in ralloc.c.  */
+
+void
+refill_memory_reserve ()
+{
+  if (spare_memory == 0)
+    spare_memory = (char *) malloc ((size_t) SPARE_MEMORY);
+}
+
 \f
 /* Arranging to disable input signals while we're in malloc.
 
    This only works with GNU malloc.  To help out systems which can't
    use GNU malloc, all the calls to malloc, realloc, and free
    elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT
-   pairs; unfortunately, we have no idea what C library functions
+   pair; unfortunately, we have no idea what C library functions
    might call malloc, so we can't really protect them unless you're
    using GNU malloc.  Fortunately, most of the major operating systems
    can use GNU malloc.  */
 
-#ifndef SYSTEM_MALLOC
+#ifndef SYNC_INPUT
+
 #ifndef DOUG_LEA_MALLOC
 extern void * (*__malloc_hook) P_ ((size_t));
 extern void * (*__realloc_hook) P_ ((void *, size_t));
@@ -1180,20 +1218,6 @@ emacs_blocked_free (ptr)
 }
 
 
-/* If we released our reserve (due to running out of memory),
-   and we have a fair amount free once again,
-   try to set aside another reserve in case we run out once more.
-
-   This is called when a relocatable block is freed in ralloc.c.  */
-
-void
-refill_memory_reserve ()
-{
-  if (spare_memory == 0)
-    spare_memory = (char *) malloc ((size_t) SPARE_MEMORY);
-}
-
-
 /* This function is the malloc hook that Emacs uses.  */
 
 static void *
@@ -1345,6 +1369,7 @@ uninterrupt_malloc ()
   __realloc_hook = emacs_blocked_realloc;
 }
 
+#endif /* not SYNC_INPUT */
 #endif /* not SYSTEM_MALLOC */
 
 
@@ -1489,7 +1514,7 @@ mark_interval_tree (tree)
 #ifndef make_number
 Lisp_Object
 make_number (n)
-     int n;
+     EMACS_INT n;
 {
   Lisp_Object obj;
   obj.s.val = n;
@@ -1665,7 +1690,7 @@ static int total_string_size;
 
 /* We check for overrun in string data blocks by appending a small
    "cookie" after each allocated string data block, and check for the
-   presense of this cookie during GC.  */
+   presence of this cookie during GC.  */
 
 #define GC_STRING_OVERRUN_COOKIE_SIZE  4
 static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
@@ -1920,14 +1945,18 @@ allocate_string_data (s, nchars, nbytes)
          mmap'ed data typically have an address towards the top of the
          address space, which won't fit into an EMACS_INT (at least on
          32-bit systems with the current tagging scheme).  --fx  */
+      BLOCK_INPUT;
       mallopt (M_MMAP_MAX, 0);
+      UNBLOCK_INPUT;
 #endif
 
       b = (struct sblock *) lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP);
 
 #ifdef DOUG_LEA_MALLOC
       /* Back to a reasonable maximum of mmap'ed areas. */
+      BLOCK_INPUT;
       mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
+      UNBLOCK_INPUT;
 #endif
 
       b->next_free = &b->first_data;
@@ -2997,18 +3026,18 @@ The property's value should be an integer between 0 and 10.  */)
 }
 
 
-/* Return a newly created sub char table with default value DEFALT.
+/* Return a newly created sub char table with slots initialized by INIT.
    Since a sub char table does not appear as a top level Emacs Lisp
    object, we don't need a Lisp interface to make it.  */
 
 Lisp_Object
-make_sub_char_table (defalt)
-     Lisp_Object defalt;
+make_sub_char_table (init)
+     Lisp_Object init;
 {
   Lisp_Object vector
-    = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), Qnil);
+    = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init);
   XCHAR_TABLE (vector)->top = Qnil;
-  XCHAR_TABLE (vector)->defalt = defalt;
+  XCHAR_TABLE (vector)->defalt = Qnil;
   XSETCHAR_TABLE (vector, XCHAR_TABLE (vector));
   return vector;
 }
@@ -4670,6 +4699,8 @@ returns nil, because real GC can't be done.  */)
   if (pure_bytes_used_before_overflow)
     return Qnil;
 
+  CHECK_CONS_LIST ();
+
   /* Don't keep undo information around forever.
      Do this early on, so it is no problem if the user quits.  */
   {
@@ -4681,7 +4712,7 @@ returns nil, because real GC can't be done.  */)
           turned off in that buffer.  Calling truncate_undo_list on
           Qt tends to return NULL, which effectively turns undo back on.
           So don't call truncate_undo_list if undo_list is Qt.  */
-       if (! EQ (nextb->undo_list, Qt))
+       if (! NILP (nextb->name) && ! EQ (nextb->undo_list, Qt))
          truncate_undo_list (nextb);
 
        /* Shrink buffer gaps, but skip indirect and dead buffers.  */
@@ -4793,6 +4824,10 @@ returns nil, because real GC can't be done.  */)
     }
   mark_backtrace ();
 
+#ifdef HAVE_WINDOW_SYSTEM
+  mark_fringe_data ();
+#endif
+
 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
   mark_stack ();
 #endif
@@ -4859,6 +4894,8 @@ returns nil, because real GC can't be done.  */)
 
   UNBLOCK_INPUT;
 
+  CHECK_CONS_LIST ();
+
   /* clear_marks (); */
   gc_in_progress = 0;
 
@@ -4866,6 +4903,24 @@ returns nil, because real GC can't be done.  */)
   if (gc_cons_threshold < 10000)
     gc_cons_threshold = 10000;
 
+  if (FLOATP (Vgc_cons_percentage))
+    { /* Set gc_cons_combined_threshold.  */
+      EMACS_INT total = 0;
+
+      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_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);
+      
+      gc_relative_threshold = total * XFLOAT_DATA (Vgc_cons_percentage);
+    }
+  else
+    gc_relative_threshold = 0;
+
   if (garbage_collection_messages)
     {
       if (message_p || minibuf_level > 0)
@@ -5955,6 +6010,8 @@ init_alloc_once ()
   staticidx = 0;
   consing_since_gc = 0;
   gc_cons_threshold = 100000 * sizeof (Lisp_Object);
+  gc_relative_threshold = 0;
+
 #ifdef VIRT_ADDR_VARIES
   malloc_sbrk_unused = 1<<22;  /* A large number */
   malloc_sbrk_used = 100000;   /* as reasonable as any number */
@@ -5986,7 +6043,15 @@ allocated since the last garbage collection.  All data types count.
 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.  */);
@@ -6053,6 +6118,7 @@ The time is in seconds as a floating point value.  */);
   DEFVAR_INT ("gcs-done", &gcs_done,
              doc: /* Accumulated number of garbage collections done.  */);
 
+  defsubr (&Smemory_full_p);
   defsubr (&Scons);
   defsubr (&Slist);
   defsubr (&Svector);