(undo_limit, undo_strong_limit, Vundo_outer_limit): Quadruple undo
[bpt/emacs.git] / src / alloc.c
index ed003af..1be5e2b 100644 (file)
@@ -1,13 +1,14 @@
 /* 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, 2005, 2006, 2007  Free Software Foundation, Inc.
+      2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 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., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -241,7 +240,7 @@ static int total_free_floats, total_floats;
    out of memory.  We keep one large block, four cons-blocks, and
    two string blocks.  */
 
-char *spare_memory[7];
+static char *spare_memory[7];
 
 /* Amount of spare memory to keep in large reserve block.  */
 
@@ -324,13 +323,13 @@ Lisp_Object Vmemory_signal_data;
 
 /* Buffer in which we save a copy of the C stack at each GC.  */
 
-char *stack_copy;
-int stack_copy_size;
+static char *stack_copy;
+static int stack_copy_size;
 
 /* Non-zero means ignore malloc warnings.  Set during initialization.
    Currently not used.  */
 
-int ignore_warnings;
+static int ignore_warnings;
 
 Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots;
 
@@ -352,8 +351,6 @@ 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 */
 
 static struct Lisp_String *allocate_string P_ ((void));
@@ -397,12 +394,12 @@ void refill_memory_reserve ();
 /* A unique object in pure space used to make some Lisp objects
    on free lists recognizable in O(1).  */
 
-Lisp_Object Vdead;
+static Lisp_Object Vdead;
 
 #ifdef GC_MALLOC_CHECK
 
 enum mem_type allocated_mem_type;
-int dont_register_blocks;
+static int dont_register_blocks;
 
 #endif /* GC_MALLOC_CHECK */
 
@@ -502,12 +499,12 @@ struct gcpro *gcprolist;
 /* Addresses of staticpro'd variables.  Initialize it to a nonzero
    value; otherwise some compilers put it into BSS.  */
 
-#define NSTATICS 0x600
-Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
+#define NSTATICS 0x640
+static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
 
 /* Index of next unused slot in staticvec.  */
 
-int staticidx = 0;
+static int staticidx = 0;
 
 static POINTER_TYPE *pure_alloc P_ ((size_t, int));
 
@@ -800,6 +797,8 @@ void
 xfree (block)
      POINTER_TYPE *block;
 {
+  if (!block)
+    return;
   MALLOC_BLOCK_INPUT;
   free (block);
   MALLOC_UNBLOCK_INPUT;
@@ -1153,6 +1152,8 @@ allocate_buffer ()
   struct buffer *b
     = (struct buffer *) lisp_malloc (sizeof (struct buffer),
                                     MEM_TYPE_BUFFER);
+  b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
+  XSETPVECTYPE (b, PVEC_BUFFER);
   return b;
 }
 
@@ -1365,6 +1366,7 @@ void
 uninterrupt_malloc ()
 {
 #ifdef HAVE_GTK_AND_PTHREAD
+#ifdef DOUG_LEA_MALLOC
   pthread_mutexattr_t attr;
 
   /*  GLIBC has a faster way to do this, but lets keep it portable.
@@ -1372,6 +1374,11 @@ uninterrupt_malloc ()
   pthread_mutexattr_init (&attr);
   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
   pthread_mutex_init (&alloc_mutex, &attr);
+#else  /* !DOUG_LEA_MALLOC */
+  /* Some systems such as Solaris 2.6 doesn't have a recursive mutex,
+     and the bundled gmalloc.c doesn't require it.  */
+  pthread_mutex_init (&alloc_mutex, NULL);
+#endif /* !DOUG_LEA_MALLOC */
 #endif /* HAVE_GTK_AND_PTHREAD */
 
   if (__free_hook != emacs_blocked_free)
@@ -1415,7 +1422,7 @@ struct interval_block
 /* Current interval block.  Its `next' pointer points to older
    blocks.  */
 
-struct interval_block *interval_block;
+static struct interval_block *interval_block;
 
 /* Index in interval_block above of the next unused interval
    structure.  */
@@ -1432,7 +1439,7 @@ INTERVAL interval_free_list;
 
 /* Total number of interval blocks now in use.  */
 
-int n_interval_blocks;
+static int n_interval_blocks;
 
 
 /* Initialize interval allocation.  */
@@ -1534,7 +1541,7 @@ mark_interval_tree (tree)
   } while (0)
 
 \f
-/* Number support.  If NO_UNION_TYPE isn't in effect, we
+/* Number support.  If USE_LISP_UNION_TYPE is in effect, we
    can't create number objects in macros.  */
 #ifndef make_number
 Lisp_Object
@@ -1754,7 +1761,7 @@ static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
 
 /* Initialize string allocation.  Called from init_alloc_once.  */
 
-void
+static void
 init_strings ()
 {
   total_strings = total_free_strings = total_string_size = 0;
@@ -1771,8 +1778,8 @@ init_strings ()
 
 static int check_string_bytes_count;
 
-void check_string_bytes P_ ((int));
-void check_sblock P_ ((struct sblock *));
+static void check_string_bytes P_ ((int));
+static void check_sblock P_ ((struct sblock *));
 
 #define CHECK_STRING_BYTES(S)  STRING_BYTES (S)
 
@@ -1793,7 +1800,7 @@ string_bytes (s)
 
 /* Check validity of Lisp strings' string_bytes member in B.  */
 
-void
+static void
 check_sblock (b)
      struct sblock *b;
 {
@@ -1827,7 +1834,7 @@ check_sblock (b)
    non-zero means check all strings, otherwise check only most
    recently allocated strings.  Used for hunting a bug.  */
 
-void
+static void
 check_string_bytes (all_p)
      int all_p;
 {
@@ -1925,11 +1932,7 @@ allocate_string ()
   consing_since_gc += sizeof *s;
 
 #ifdef GC_CHECK_STRING_BYTES
-  if (!noninteractive
-#ifdef MAC_OS8
-      && current_sblock
-#endif
-     )
+  if (!noninteractive)
     {
       if (++check_string_bytes_count == 200)
        {
@@ -2580,7 +2583,7 @@ struct Lisp_Float *float_free_list;
 
 /* Initialize float allocation.  */
 
-void
+static void
 init_float ()
 {
   float_block = NULL;
@@ -2592,7 +2595,7 @@ init_float ()
 
 /* Explicitly free a float cell by putting it on the free-list.  */
 
-void
+static void
 free_float (ptr)
      struct Lisp_Float *ptr;
 {
@@ -2699,12 +2702,12 @@ struct Lisp_Cons *cons_free_list;
 
 /* Total number of cons blocks now in use.  */
 
-int n_cons_blocks;
+static int n_cons_blocks;
 
 
 /* Initialize cons allocation.  */
 
-void
+static void
 init_cons ()
 {
   cons_block = NULL;
@@ -2901,11 +2904,11 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
 
 /* Singly-linked list of all vectors.  */
 
-struct Lisp_Vector *all_vectors;
+static struct Lisp_Vector *all_vectors;
 
 /* Total number of vector-like objects now in use.  */
 
-int n_vectors;
+static int n_vectors;
 
 
 /* Value is a pointer to a newly allocated Lisp_Vector structure
@@ -2965,7 +2968,7 @@ allocate_vector (nslots)
 
 /* Allocate other vector-like structures.  */
 
-static struct Lisp_Vector *
+struct Lisp_Vector *
 allocate_pseudovector (memlen, lisplen, tag)
      int memlen, lisplen;
      EMACS_INT tag;
@@ -2981,10 +2984,6 @@ allocate_pseudovector (memlen, lisplen, tag)
   XSETPVECTYPE (v, tag);       /* Add the appropriate tag.  */
   return v;
 }
-#define ALLOCATE_PSEUDOVECTOR(typ,field,tag)                           \
-  ((typ*)                                                              \
-   allocate_pseudovector                                               \
-       (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
 
 struct Lisp_Hash_Table *
 allocate_hash_table (void)
@@ -3031,22 +3030,6 @@ allocate_process ()
 }
 
 
-/* Only used for PVEC_WINDOW_CONFIGURATION. */
-struct Lisp_Vector *
-allocate_other_vector (len)
-     EMACS_INT len;
-{
-  struct Lisp_Vector *v = allocate_vectorlike (len);
-  EMACS_INT i;
-
-  for (i = 0; i < len; ++i)
-    v->contents[i] = Qnil;
-  v->size = len;
-
-  return v;
-}
-
-
 DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
        doc: /* Return a newly created vector of length LENGTH, with each element being INIT.
 See also the function `vector'.  */)
@@ -3155,21 +3138,21 @@ struct symbol_block
 /* Current symbol block and index of first unused Lisp_Symbol
    structure in it.  */
 
-struct symbol_block *symbol_block;
-int symbol_block_index;
+static struct symbol_block *symbol_block;
+static int symbol_block_index;
 
 /* List of free symbols.  */
 
-struct Lisp_Symbol *symbol_free_list;
+static struct Lisp_Symbol *symbol_free_list;
 
 /* Total number of symbol blocks now in use.  */
 
-int n_symbol_blocks;
+static int n_symbol_blocks;
 
 
 /* Initialize symbol allocation.  */
 
-void
+static void
 init_symbol ()
 {
   symbol_block = NULL;
@@ -3251,16 +3234,16 @@ struct marker_block
   struct marker_block *next;
 };
 
-struct marker_block *marker_block;
-int marker_block_index;
+static struct marker_block *marker_block;
+static int marker_block_index;
 
-union Lisp_Misc *marker_free_list;
+static union Lisp_Misc *marker_free_list;
 
 /* Total number of marker blocks now in use.  */
 
-int n_marker_blocks;
+static int n_marker_blocks;
 
-void
+static void
 init_marker ()
 {
   marker_block = NULL;
@@ -3307,7 +3290,7 @@ allocate_misc ()
   --total_free_markers;
   consing_since_gc += sizeof (union Lisp_Misc);
   misc_objects_consed++;
-  XMARKER (val)->gcmarkbit = 0;
+  XMISCANY (val)->gcmarkbit = 0;
   return val;
 }
 
@@ -3317,7 +3300,7 @@ void
 free_misc (misc)
      Lisp_Object misc;
 {
-  XMISC (misc)->u_marker.type = Lisp_Misc_Free;
+  XMISCTYPE (misc) = Lisp_Misc_Free;
   XMISC (misc)->u_free.chain = marker_free_list;
   marker_free_list = XMISC (misc);
 
@@ -4033,7 +4016,7 @@ live_misc_p (m, p)
              && offset < (MARKER_BLOCK_SIZE * sizeof b->markers[0])
              && (b != marker_block
                  || offset / sizeof b->markers[0] < marker_block_index)
-             && ((union Lisp_Misc *) p)->u_marker.type != Lisp_Misc_Free);
+             && ((union Lisp_Misc *) p)->u_any.type != Lisp_Misc_Free);
     }
   else
     return 0;
@@ -4164,7 +4147,7 @@ mark_maybe_object (obj)
          break;
 
        case Lisp_Misc:
-         mark_p = (live_misc_p (m, po) && !XMARKER (obj)->gcmarkbit);
+         mark_p = (live_misc_p (m, po) && !XMISCANY (obj)->gcmarkbit);
          break;
 
        case Lisp_Int:
@@ -4504,8 +4487,12 @@ mark_stack ()
   /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
      needed on ia64 too.  See mach_dep.c, where it also says inline
      assembler doesn't work with relevant proprietary compilers.  */
-#ifdef sparc
+#ifdef __sparc__
+#ifdef __sparc64__
+  asm ("flushw");
+#else
   asm ("ta 3");
+#endif
 #endif
 
   /* Save registers that we need to see on the stack.  We need to see
@@ -4557,7 +4544,7 @@ mark_stack ()
 
 
 /* Determine whether it is safe to access memory at address P.  */
-int
+static int
 valid_pointer_p (p)
      void *p;
 {
@@ -4853,7 +4840,7 @@ pure_cons (car, cdr)
 
 /* Value is a float object with value NUM allocated from pure space.  */
 
-Lisp_Object
+static Lisp_Object
 make_pure_float (num)
      double num;
 {
@@ -5345,48 +5332,20 @@ mark_face_cache (c)
 }
 
 
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Mark Lisp objects in image IMG.  */
-
-static void
-mark_image (img)
-     struct image *img;
-{
-  mark_object (img->spec);
-
-  if (!NILP (img->data.lisp_val))
-    mark_object (img->data.lisp_val);
-}
-
-
-/* Mark Lisp objects in image cache of frame F.  It's done this way so
-   that we don't have to include xterm.h here.  */
-
-static void
-mark_image_cache (f)
-     struct frame *f;
-{
-  forall_images_in_image_cache (f, mark_image);
-}
-
-#endif /* HAVE_X_WINDOWS */
-
-
 \f
 /* Mark reference to a Lisp_Object.
    If the object referred to has not been seen yet, recursively mark
    all the references contained in it.  */
 
 #define LAST_MARKED_SIZE 500
-Lisp_Object last_marked[LAST_MARKED_SIZE];
+static Lisp_Object last_marked[LAST_MARKED_SIZE];
 int last_marked_index;
 
 /* For debugging--call abort when we cdr down this many
    links of a list, in mark_object.  In debugging,
    the call to abort will hit a breakpoint.
    Normally this is zero and the check never goes off.  */
-int mark_object_loop_halt;
+static int mark_object_loop_halt;
 
 /* Return non-zero if the object was not yet marked.  */
 static int
@@ -5401,7 +5360,7 @@ mark_vectorlike (ptr)
   VECTOR_MARK (ptr);           /* Else mark it */
   if (size & PSEUDOVECTOR_FLAG)
     size &= PSEUDOVECTOR_SIZE_MASK;
-  
+
   /* Note that this size is not the memory-footprint size, but only
      the number of Lisp_Object fields that we should trace.
      The distinction is used e.g. by Lisp_Process which places extra
@@ -5541,12 +5500,7 @@ mark_object (arg)
        {
          register struct frame *ptr = XFRAME (obj);
          if (mark_vectorlike (XVECTOR (obj)))
-           {
-             mark_face_cache (ptr->face_cache);
-#ifdef HAVE_WINDOW_SYSTEM
-             mark_image_cache (ptr);
-#endif /* HAVE_WINDOW_SYSTEM */
-           }
+           mark_face_cache (ptr->face_cache);
        }
       else if (WINDOWP (obj))
        {
@@ -5613,14 +5567,13 @@ mark_object (arg)
 
     case Lisp_Misc:
       CHECK_ALLOCATED_AND_LIVE (live_misc_p);
-      if (XMARKER (obj)->gcmarkbit)
+      if (XMISCANY (obj)->gcmarkbit)
        break;
-      XMARKER (obj)->gcmarkbit = 1;
+      XMISCANY (obj)->gcmarkbit = 1;
 
       switch (XMISCTYPE (obj))
        {
        case Lisp_Misc_Buffer_Local_Value:
-       case Lisp_Misc_Some_Buffer_Local_Value:
          {
            register struct Lisp_Buffer_Local_Value *ptr
              = XBUFFER_LOCAL_VALUE (obj);
@@ -5757,6 +5710,8 @@ mark_buffer (buf)
       mark_object (tmp);
     }
 
+  /* buffer-local Lisp variables start at `undo_list',
+     tho only the ones from `name' on are GC'd normally.  */
   for (ptr = &buffer->name;
        (char *)ptr < (char *)buffer + sizeof (struct buffer);
        ptr++)
@@ -5780,6 +5735,9 @@ mark_terminals (void)
   for (t = terminal_list; t; t = t->next_terminal)
     {
       eassert (t->name != NULL);
+#ifdef HAVE_WINDOW_SYSTEM
+      mark_image_cache (t->image_cache);
+#endif /* HAVE_WINDOW_SYSTEM */
       mark_vectorlike ((struct Lisp_Vector *)t);
     }
 }
@@ -5806,7 +5764,7 @@ survives_gc_p (obj)
       break;
 
     case Lisp_Misc:
-      survives_p = XMARKER (obj)->gcmarkbit;
+      survives_p = XMISCANY (obj)->gcmarkbit;
       break;
 
     case Lisp_String:
@@ -6103,9 +6061,9 @@ gc_sweep ()
 
        for (i = 0; i < lim; i++)
          {
-           if (!mblk->markers[i].u_marker.gcmarkbit)
+           if (!mblk->markers[i].u_any.gcmarkbit)
              {
-               if (mblk->markers[i].u_marker.type == Lisp_Misc_Marker)
+               if (mblk->markers[i].u_any.type == Lisp_Misc_Marker)
                  unchain_marker (&mblk->markers[i].u_marker);
                /* Set the type of the freed object to Lisp_Misc_Free.
                   We could leave the type alone, since nobody checks it,
@@ -6118,7 +6076,7 @@ gc_sweep ()
            else
              {
                num_used++;
-               mblk->markers[i].u_marker.gcmarkbit = 0;
+               mblk->markers[i].u_any.gcmarkbit = 0;
              }
          }
        lim = MARKER_BLOCK_SIZE;
@@ -6250,13 +6208,14 @@ Frames, windows, buffers, and subprocesses count as vectors
 }
 
 int suppress_checking;
+
 void
 die (msg, file, line)
      const char *msg;
      const char *file;
      int line;
 {
-  fprintf (stderr, "\r\nEmacs fatal error: %s:%d: %s\r\n",
+  fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
           file, line, msg);
   abort ();
 }
@@ -6294,6 +6253,7 @@ init_alloc_once ()
   init_marker ();
   init_float ();
   init_intervals ();
+  init_weak_hash_tables ();
 
 #ifdef REL_ALLOC
   malloc_hysteresis = 32;