]> code.delx.au - gnu-emacs/blobdiff - src/alloc.c
*** empty log message ***
[gnu-emacs] / src / alloc.c
index d83a6bbf2ee4550e23ceb2708e5973e5340ebc8a..728c5f9557282152c0e52fbd9c62981270f5e22f 100644 (file)
@@ -22,6 +22,10 @@ Boston, MA 02111-1307, USA.  */
 #include <config.h>
 #include <stdio.h>
 
+#ifdef ALLOC_DEBUG
+#undef INLINE
+#endif
+
 /* Note that this declares bzero on OSF/1.  How dumb.  */
 
 #include <signal.h>
@@ -122,18 +126,18 @@ int consing_since_gc;
 
 /* Count the amount of consing of various sorts of space.  */
 
-int cons_cells_consed;
-int floats_consed;
-int vector_cells_consed;
-int symbols_consed;
-int string_chars_consed;
-int misc_objects_consed;
-int intervals_consed;
-int strings_consed;
+EMACS_INT cons_cells_consed;
+EMACS_INT floats_consed;
+EMACS_INT vector_cells_consed;
+EMACS_INT symbols_consed;
+EMACS_INT string_chars_consed;
+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. */
 
-int gc_cons_threshold;
+EMACS_INT gc_cons_threshold;
 
 /* Nonzero during GC.  */
 
@@ -155,8 +159,8 @@ int malloc_sbrk_unused;
 
 /* Two limits controlling how much undo information to keep.  */
 
-int undo_limit;
-int undo_strong_limit;
+EMACS_INT undo_limit;
+EMACS_INT undo_strong_limit;
 
 /* Number of live and free conses etc.  */
 
@@ -181,6 +185,10 @@ static int malloc_hysteresis;
 
 Lisp_Object Vpurify_flag;
 
+/* Non-nil means we are handling a memory-full error.  */
+
+Lisp_Object Vmemory_full;
+
 #ifndef HAVE_SHM
 
 /* Force it into data space! */
@@ -215,7 +223,7 @@ static size_t pure_bytes_used_before_overflow;
 
 /* Index in pure at which next pure object will be allocated.. */
 
-int pure_bytes_used;
+EMACS_INT pure_bytes_used;
 
 /* If nonzero, this is a warning delivered by malloc and not yet
    displayed.  */
@@ -224,7 +232,7 @@ char *pending_malloc_warning;
 
 /* Pre-computed signal argument for use when memory is exhausted.  */
 
-Lisp_Object memory_signal_data;
+Lisp_Object Vmemory_signal_data;
 
 /* Maximum amount of C stack to save when a GC happens.  */
 
@@ -396,7 +404,7 @@ struct gcpro *gcprolist;
 
 /* Addresses of staticpro'd variables.  */
 
-#define NSTATICS 1026
+#define NSTATICS 1280
 Lisp_Object *staticvec[NSTATICS] = {0};
 
 /* Index of next unused slot in staticvec.  */
@@ -418,23 +426,7 @@ static POINTER_TYPE *pure_alloc P_ ((size_t, int));
                                Malloc
  ************************************************************************/
 
-/* Write STR to Vstandard_output plus some advice on how to free some
-   memory.  Called when memory gets low.  */
-
-Lisp_Object
-malloc_warning_1 (str)
-     Lisp_Object str;
-{
-  Fprinc (str, Vstandard_output);
-  write_string ("\nKilling some buffers may delay running out of memory.\n", -1);
-  write_string ("However, certainly by the time you receive the 95% warning,\n", -1);
-  write_string ("you should clean up, kill this Emacs, and start a new one.", -1);
-  return Qnil;
-}
-
-
-/* Function malloc calls this if it finds we are near exhausting
-   storage.  */
+/* Function malloc calls this if it finds we are near exhausting storage.  */
 
 void
 malloc_warning (str)
@@ -444,16 +436,16 @@ malloc_warning (str)
 }
 
 
-/* Display a malloc warning in buffer *Danger*.  */
+/* Display an already-pending malloc warning.  */
 
 void
 display_malloc_warning ()
 {
-  register Lisp_Object val;
-
-  val = build_string (pending_malloc_warning);
+  call3 (intern ("display-warning"),
+        intern ("alloc"),
+        build_string (pending_malloc_warning),
+        intern ("emergency"));
   pending_malloc_warning = 0;
-  internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val);
 }
 
 
@@ -469,6 +461,8 @@ display_malloc_warning ()
 void
 memory_full ()
 {
+  Vmemory_full = Qt;
+
 #ifndef SYSTEM_MALLOC
   bytes_used_when_full = BYTES_USED;
 #endif
@@ -483,7 +477,7 @@ memory_full ()
   /* This used to call error, but if we've run out of memory, we could
      get infinite recursion trying to build the string.  */
   while (1)
-    Fsignal (Qnil, memory_signal_data);
+    Fsignal (Qnil, Vmemory_signal_data);
 }
 
 
@@ -503,10 +497,12 @@ buffer_memory_full ()
   memory_full ();
 #endif
 
+  Vmemory_full = Qt;
+
   /* This used to call error, but if we've run out of memory, we could
      get infinite recursion trying to build the string.  */
   while (1)
-    Fsignal (Qerror, memory_signal_data);
+    Fsignal (Qnil, Vmemory_signal_data);
 }
 
 
@@ -567,7 +563,7 @@ xfree (block)
 
 char *
 xstrdup (s)
-     char *s;
+     const char *s;
 {
   size_t len = strlen (s) + 1;
   char *p = (char *) xmalloc (len);
@@ -1341,7 +1337,7 @@ allocate_string ()
 
 #ifdef GC_CHECK_STRING_BYTES
   if (!noninteractive
-#ifdef macintosh
+#ifdef MAC_OS8
       && current_sblock
 #endif
      )
@@ -1676,8 +1672,8 @@ Both LENGTH and INIT must be numbers.  */)
     {
       nbytes = XINT (length);
       val = make_uninit_string (nbytes);
-      p = XSTRING (val)->data;
-      end = p + XSTRING (val)->size;
+      p = SDATA (val);
+      end = p + SCHARS (val);
       while (p != end)
        *p++ = c;
     }
@@ -1688,7 +1684,7 @@ Both LENGTH and INIT must be numbers.  */)
 
       nbytes = len * XINT (length);
       val = make_uninit_multibyte_string (XINT (length), nbytes);
-      p = XSTRING (val)->data;
+      p = SDATA (val);
       end = p + nbytes;
       while (p != end)
        {
@@ -1749,7 +1745,7 @@ LENGTH must be a number.  INIT matters only in whether it is t or nil.  */)
 
 Lisp_Object
 make_string (contents, nbytes)
-     char *contents;
+     const char *contents;
      int nbytes;
 {
   register Lisp_Object val;
@@ -1770,13 +1766,13 @@ make_string (contents, nbytes)
 
 Lisp_Object
 make_unibyte_string (contents, length)
-     char *contents;
+     const char *contents;
      int length;
 {
   register Lisp_Object val;
   val = make_uninit_string (length);
-  bcopy (contents, XSTRING (val)->data, length);
-  SET_STRING_BYTES (XSTRING (val), -1);
+  bcopy (contents, SDATA (val), length);
+  STRING_SET_UNIBYTE (val);
   return val;
 }
 
@@ -1786,12 +1782,12 @@ make_unibyte_string (contents, length)
 
 Lisp_Object
 make_multibyte_string (contents, nchars, nbytes)
-     char *contents;
+     const char *contents;
      int nchars, nbytes;
 {
   register Lisp_Object val;
   val = make_uninit_multibyte_string (nchars, nbytes);
-  bcopy (contents, XSTRING (val)->data, nbytes);
+  bcopy (contents, SDATA (val), nbytes);
   return val;
 }
 
@@ -1806,9 +1802,9 @@ make_string_from_bytes (contents, nchars, nbytes)
 {
   register Lisp_Object val;
   val = make_uninit_multibyte_string (nchars, nbytes);
-  bcopy (contents, XSTRING (val)->data, nbytes);
-  if (STRING_BYTES (XSTRING (val)) == XSTRING (val)->size)
-    SET_STRING_BYTES (XSTRING (val), -1);
+  bcopy (contents, SDATA (val), nbytes);
+  if (SBYTES (val) == SCHARS (val))
+    STRING_SET_UNIBYTE (val);
   return val;
 }
 
@@ -1825,9 +1821,9 @@ make_specified_string (contents, nchars, nbytes, multibyte)
 {
   register Lisp_Object val;
   val = make_uninit_multibyte_string (nchars, nbytes);
-  bcopy (contents, XSTRING (val)->data, nbytes);
+  bcopy (contents, SDATA (val), nbytes);
   if (!multibyte)
-    SET_STRING_BYTES (XSTRING (val), -1);
+    STRING_SET_UNIBYTE (val);
   return val;
 }
 
@@ -1837,7 +1833,7 @@ make_specified_string (contents, nchars, nbytes, multibyte)
 
 Lisp_Object
 build_string (str)
-     char *str;
+     const char *str;
 {
   return make_string (str, strlen (str));
 }
@@ -1852,7 +1848,7 @@ make_uninit_string (length)
 {
   Lisp_Object val;
   val = make_uninit_multibyte_string (length, length);
-  SET_STRING_BYTES (XSTRING (val), -1);
+  STRING_SET_UNIBYTE (val);
   return val;
 }
 
@@ -2545,7 +2541,7 @@ Its value and function definition are void, and its property list is nil.  */)
     }
   
   p = XSYMBOL (val);
-  p->name = XSTRING (name);
+  p->xname = name;
   p->plist = Qnil;
   p->value = Qunbound;
   p->function = Qunbound;
@@ -2693,10 +2689,10 @@ make_event_array (nargs, args)
     result = Fmake_string (make_number (nargs), make_number (0));
     for (i = 0; i < nargs; i++)
       {
-       XSTRING (result)->data[i] = XINT (args[i]);
+       SSET (result, i, XINT (args[i]));
        /* Move the meta bit to the right place for a string char.  */
        if (XINT (args[i]) & CHAR_META)
-         XSTRING (result)->data[i] |= 0x80;
+         SSET (result, i, SREF (result, i) | 0x80);
       }
     
     return result;
@@ -3837,14 +3833,14 @@ pure_alloc (size, type)
 }
 
 
-/* Signal an error if PURESIZE is too small.  */
+/* Print a warning if PURESIZE is too small.  */
 
 void
 check_pure_size ()
 {
   if (pure_bytes_used_before_overflow)
-    error ("Pure Lisp storage overflow (approx. %d bytes needed)",
-          (int) (pure_bytes_used + pure_bytes_used_before_overflow));
+    message ("Pure Lisp storage overflow (approx. %d bytes needed)",
+            (int) (pure_bytes_used + pure_bytes_used_before_overflow));
 }
 
 
@@ -3947,8 +3943,8 @@ Does not copy symbols.  Copies strings without text properties.  */)
   else if (FLOATP (obj))
     return make_pure_float (XFLOAT_DATA (obj));
   else if (STRINGP (obj))
-    return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size,
-                            STRING_BYTES (XSTRING (obj)),
+    return make_pure_string (SDATA (obj), SCHARS (obj),
+                            SBYTES (obj),
                             STRING_MULTIBYTE (obj));
   else if (COMPILEDP (obj) || VECTORP (obj))
     {
@@ -4020,7 +4016,7 @@ struct backtrace
 int
 inhibit_garbage_collection ()
 {
-  int count = specpdl_ptr - specpdl;
+  int count = SPECPDL_INDEX ();
   int nbits = min (VALBITS, BITS_PER_INT);
 
   specbind (Qgc_cons_threshold, make_number (((EMACS_INT) 1 << (nbits - 1)) - 1));
@@ -4048,7 +4044,7 @@ Garbage collection happens automatically if you cons more than
   register int i;
   int message_p;
   Lisp_Object total[8];
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
 
   /* Can't GC if pure storage overflowed because we can't determine
      if something is a pure object or not.  */
@@ -4061,7 +4057,7 @@ Garbage collection happens automatically if you cons more than
 
   /* Save what's currently displayed in the echo area.  */
   message_p = push_message ();
-  record_unwind_protect (push_message_unwind, Qnil);
+  record_unwind_protect (pop_message_unwind, Qnil);
 
   /* Save a copy of the contents of the stack, for debugging.  */
 #if MAX_SAVE_STACK > 0
@@ -4419,6 +4415,12 @@ mark_image_cache (f)
 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;
+
 void
 mark_object (argptr)
      Lisp_Object *argptr;
@@ -4429,6 +4431,7 @@ mark_object (argptr)
   void *po;
   struct mem_node *m;
 #endif
+  int cdr_count = 0;
 
  loop:
   obj = *objptr;
@@ -4690,9 +4693,9 @@ mark_object (argptr)
        mark_object (&ptr->function);
        mark_object (&ptr->plist);
 
-       if (!PURE_POINTER_P (ptr->name))
-         MARK_STRING (ptr->name);
-       MARK_INTERVAL_TREE (ptr->name->intervals);
+       if (!PURE_POINTER_P (XSTRING (ptr->xname)))
+         MARK_STRING (XSTRING (ptr->xname));
+       MARK_INTERVAL_TREE (STRING_INTERVALS (ptr->xname));
        
        /* Note that we do not mark the obarray of the symbol.
           It is safe not to do so because nothing accesses that
@@ -4782,10 +4785,14 @@ mark_object (argptr)
        if (EQ (ptr->cdr, Qnil))
          {
            objptr = &ptr->car;
+           cdr_count = 0;
            goto loop;
          }
        mark_object (&ptr->car);
        objptr = &ptr->cdr;
+       cdr_count++;
+       if (cdr_count == mark_object_loop_halt)
+         abort ();
        goto loop;
       }
 
@@ -4892,6 +4899,7 @@ mark_kboards ()
       mark_object (&kb->Vsystem_key_alist);
       mark_object (&kb->system_key_syms);
       mark_object (&kb->Vdefault_minibuffer_frame);
+      mark_object (&kb->echo_string);
     }
 }
 
@@ -5162,7 +5170,7 @@ gc_sweep ()
            /* Check if the symbol was created during loadup.  In such a case
               it might be pointed to by pure bytecode which we don't trace,
               so we conservatively assume that it is live.  */
-           int pure_p = PURE_POINTER_P (sym->name);
+           int pure_p = PURE_POINTER_P (XSTRING (sym->xname));
            
            if (!XMARKBIT (sym->plist) && !pure_p)
              {
@@ -5177,7 +5185,7 @@ gc_sweep ()
              {
                ++num_used;
                if (!pure_p)
-                 UNMARK_STRING (sym->name);
+                 UNMARK_STRING (XSTRING (sym->xname));
                XUNMARK (sym->plist);
              }
          }
@@ -5540,11 +5548,17 @@ which includes both saved text and other data.  */);
   Qpost_gc_hook = intern ("post-gc-hook");
   staticpro (&Qpost_gc_hook);
 
+  DEFVAR_LISP ("memory-signal-data", &Vmemory_signal_data,
+              doc: /* Precomputed `signal' argument for memory-full error.  */);
   /* We build this in advance because if we wait until we need it, we might
      not be able to allocate the memory to hold it.  */
-  memory_signal_data
-    = Fcons (Qerror, Fcons (build_string ("Memory exhausted--use M-x save-some-buffers RET"), Qnil));
-  staticpro (&memory_signal_data);
+  Vmemory_signal_data
+    = list2 (Qerror,
+            build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs"));
+
+  DEFVAR_LISP ("memory-full", &Vmemory_full,
+              doc: /* Non-nil means we are handling a memory-full error.  */);
+  Vmemory_full = Qnil;
 
   staticpro (&Qgc_cons_threshold);
   Qgc_cons_threshold = intern ("gc-cons-threshold");