home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / alloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-29  |  59.2 KB  |  2,365 lines

  1. /* Storage allocation and gc for GNU Emacs Lisp interpreter.
  2.    Copyright (C) 1985, 1986, 1988, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include "config.h"
  22. #include "lisp.h"
  23. #ifndef standalone
  24. #include "buffer.h"
  25. #include "extents.h"
  26. #include "window.h"
  27. #include "events.h"
  28. #include "keymap.h"
  29. #ifdef HAVE_X_WINDOWS
  30. #include "xterm.h"
  31. #ifdef MULTI_SCREEN
  32. #include "screen.h"
  33. #endif    /* MULTI_SCREEN */
  34. #endif    /* HAVE_X_WINDOWS */
  35. #endif
  36.  
  37. #include <stdio.h>
  38.  
  39. /* Define this to see where all that space is going... */
  40. #define PURESTAT
  41.  
  42. #include "puresize.h"
  43.  
  44. #include "backtrace.h"
  45.  
  46. #define max(A,B) ((A) > (B) ? (A) : (B))
  47.  
  48. /* Macro to verify that storage intended for Lisp objects is not
  49.    out of range to fit in the space for a pointer.
  50.    ADDRESS is the start of the block, and SIZE
  51.    is the amount of space within which objects can start.  */
  52. #define VALIDATE_LISP_STORAGE(address, size)            \
  53.   {                                \
  54.     Lisp_Object val;                        \
  55.     XSET (val, Lisp_Cons, (char *) address + size);        \
  56.     if ((char *) XCONS (val) != (char *) address + size)    \
  57.       {                                \
  58.     xfree (address);                    \
  59.     memory_full ();                        \
  60.       }                                \
  61.   }
  62.  
  63. /* Number of bytes of consing done since the last gc */
  64. int consing_since_gc;
  65. #ifdef EMACS_BTL
  66. #define INCREMENT_CONS_COUNTER(size) \
  67. { \
  68.   extern void cadillac_record_backtrace(); \
  69.   int __sz__ = ((int) (size)); \
  70.   consing_since_gc += __sz__; \
  71.   cadillac_record_backtrace (2, __sz__); \
  72. }
  73. #else
  74. #define INCREMENT_CONS_COUNTER(size) (consing_since_gc += (size))
  75. #endif
  76.  
  77. /* Number of bytes of consing since gc before another gc should be done. */
  78. int gc_cons_threshold;
  79.  
  80. /* Nonzero during gc */
  81. int gc_in_progress;
  82.  
  83. /* Nonzero when calling the hooks in Energize-beta */
  84. Lisp_Object Qgc_currently_forbidden;
  85. int gc_currently_forbidden;
  86.  
  87. #ifndef VIRT_ADDR_VARIES
  88. extern
  89. #endif /* VIRT_ADDR_VARIES */
  90.  int malloc_sbrk_used;
  91.  
  92. #ifndef VIRT_ADDR_VARIES
  93. extern
  94. #endif /* VIRT_ADDR_VARIES */
  95.  int malloc_sbrk_unused;
  96.  
  97. /* Two thresholds controlling how much undo information to keep.  */
  98. static int undo_threshold;
  99. static int undo_high_threshold;
  100.  
  101. /* Non-nil means defun should do purecopy on the function definition */
  102. Lisp_Object Vpurify_flag;
  103.  
  104. extern int pure[];    /* moved to pure.c to speed incremental linking */
  105.  
  106. #define PUREBEG (char *) pure
  107.  
  108. /* Index in pure at which next pure object will be allocated. */
  109. static int pureptr;
  110.  
  111. /* define this to keep statistics on how much of what is in purespace */
  112. #ifdef PURESTAT
  113. unsigned int purestat [2][11];
  114. #endif
  115.  
  116. /* Maximum amount of C stack to save when a GC happens.  */
  117.  
  118. #ifndef MAX_SAVE_STACK
  119. #define MAX_SAVE_STACK 16000
  120. #endif
  121.  
  122. /* Buffer in which we save a copy of the C stack at each GC.  */
  123.  
  124. static char *stack_copy;
  125. static int stack_copy_size;
  126.  
  127. /* Non-zero means ignore malloc warnings.  Set during initialization.  */
  128. int ignore_warnings;
  129.  
  130. static void pure_storage_exhausted ();
  131.  
  132. static Lisp_Object
  133. malloc_warning_1 (str)
  134.      Lisp_Object str;
  135. {
  136.   Fprinc (str, Vstandard_output);
  137.   write_string ("\nKilling some buffers may delay running out of memory.\n", -1);
  138.   write_string ("However, certainly by the time you receive the 95% warning,\n", -1);
  139.   write_string ("you should clean up, kill this Emacs, and start a new one.", -1);
  140.   return Qnil;
  141. }
  142.  
  143. /* malloc calls this if it finds we are near exhausting storage */
  144. void
  145. malloc_warning (str)
  146.      char *str;
  147. {
  148.   register Lisp_Object val;
  149.  
  150.   if (ignore_warnings)
  151.     return;
  152.  
  153.   val = build_string (str);
  154.   internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val, Qnil);
  155. }
  156.  
  157. /* Called if malloc returns zero */
  158. void
  159. memory_full ()
  160. {
  161.   /* Force a GC next time eval is called.
  162.      It's better to loop garbage-collecting (we might reclaim enough
  163.      to win) than to loop beeping and barfing "Memory exhausted"
  164.    */
  165.   consing_since_gc = gc_cons_threshold + 1;
  166.   error ("Memory exhausted");
  167. }
  168.  
  169. /* like malloc and realloc but check for no memory left, and block input. */
  170.  
  171. void *
  172. xmalloc (size)
  173.      int size;
  174. {
  175.   register void *val;
  176.  
  177.   /* It is necessary to block SIGIO interrupts around calls to malloc()
  178.      because the SIGIO handler interrogates the X queue to see if a
  179.      control-g keypress event is pending.  It does this by calling
  180.      XCheckIfEvent(), which can call malloc() in order to expand its
  181.      internal buffers.  As malloc is not reentrant, this can corrupt
  182.      the malloc lists.
  183.  
  184.      This is generally only a problem within the first few seconds after
  185.      emacs has started up, because the X event buffers tend to reach a
  186.      stable size fairly early, but it is a *potential* problem at all
  187.      times.
  188.    */
  189.   BLOCK_INPUT;
  190.   val = (void *) malloc (size);
  191.   UNBLOCK_INPUT;
  192.  
  193.   if (!val && size) memory_full ();
  194.   return val;
  195. }
  196.  
  197. void *
  198. xrealloc (block, size)
  199.      void *block;
  200.      int size;
  201. {
  202.   register void *val;
  203.  
  204.   BLOCK_INPUT;    /* see comment above */
  205.   /* We must call malloc explicitly when BLOCK is 0, since some
  206.      reallocs don't do this.  */
  207.   if (! block)
  208.     val = (void *) malloc (size);
  209.   else
  210.     val = (void *) realloc (block, size);
  211.   UNBLOCK_INPUT;
  212.  
  213.   if (!val && (size != 0)) memory_full ();
  214.   return val;
  215. }
  216.  
  217. void
  218. xfree (void *block)
  219. {
  220.   BLOCK_INPUT;
  221.   free (block);
  222.   UNBLOCK_INPUT;
  223. }
  224.  
  225.  
  226. #define EXTENT_BLOCK_SIZE \
  227.   ((1020 - sizeof (struct extent_block *)) / sizeof (struct extent))
  228.  
  229. #define DUP_BLOCK_SIZE \
  230.   ((1020 - sizeof (struct dup_block *)) / sizeof (struct extent_replica))
  231.  
  232. struct extent_block
  233.   {
  234.     struct extent_block *next;
  235.     struct extent extents[EXTENT_BLOCK_SIZE];
  236.   };
  237.  
  238. struct dup_block
  239.   {
  240.     struct dup_block *next;
  241.     struct extent_replica dups[DUP_BLOCK_SIZE];
  242.   };
  243.  
  244. static struct extent_block *extent_block;
  245. static int extent_block_index;
  246.  
  247. static EXTENT extent_free_list;
  248.  
  249. static struct dup_block *dup_block;
  250. static int dup_block_index;
  251.  
  252. static DUP dup_free_list;
  253.  
  254. static void
  255. init_extents ()
  256. {
  257.   extent_block
  258.     = (struct extent_block *) xmalloc (sizeof (struct extent_block));
  259.   extent_block->next = 0;
  260.   memset (extent_block->extents, 0, sizeof extent_block->extents);
  261.   extent_block_index = 0;
  262.   extent_free_list = 0;
  263.  
  264.   dup_block
  265.     = (struct dup_block *) xmalloc (sizeof (struct dup_block));
  266.   dup_block->next = 0;
  267.   memset (dup_block->dups, 0, sizeof dup_block->dups);
  268.   dup_block_index = 0;
  269.   dup_free_list = 0;
  270. }
  271.  
  272. EXTENT
  273. make_extent ()
  274. {
  275.   EXTENT val;
  276.  
  277.   if (extent_free_list)
  278.     {
  279.       val = extent_free_list;
  280.       extent_free_list = extent_free_list->next;
  281.       val->next = 0;
  282.     }
  283.   else
  284.     {
  285.       if (extent_block_index == EXTENT_BLOCK_SIZE)
  286.     {
  287.       register struct extent_block *newi
  288.         = (struct extent_block *) xmalloc (sizeof (struct extent_block));
  289.  
  290.       if (!newi)
  291.         memory_full ();
  292.  
  293.           memset ((char *) newi, 0, sizeof (struct extent_block));
  294.  
  295.       VALIDATE_LISP_STORAGE (newi, sizeof *newi);
  296.       newi->next = extent_block;
  297.       extent_block = newi;
  298.       extent_block_index = 0;
  299.     }
  300.       val = &extent_block->extents[extent_block_index++];
  301.     }
  302.   val->user_data = Qnil;
  303.   INCREMENT_CONS_COUNTER (sizeof (struct extent));
  304.   return val;
  305. }
  306.  
  307. DUP
  308. make_extent_replica ()
  309. {
  310.   DUP val;
  311.  
  312.   if (dup_free_list)
  313.     {
  314.       val = dup_free_list;
  315.       dup_free_list = (DUP) dup_free_list->extent;
  316.       val->extent = 0;
  317.     }
  318.   else
  319.     {
  320.       if (dup_block_index == DUP_BLOCK_SIZE)
  321.     {
  322.       struct dup_block *newd
  323.         = (struct dup_block *) xmalloc (sizeof (struct dup_block));
  324.  
  325.       if (!newd)
  326.         memory_full ();
  327.  
  328.           memset ((char *) newd, 0, sizeof(struct dup_block));
  329.  
  330.       VALIDATE_LISP_STORAGE (newd, sizeof(struct dup_block));
  331.       newd->next = dup_block;
  332.       dup_block = newd;
  333.       dup_block_index = 0;
  334.     }
  335.       val = &dup_block->dups[dup_block_index++];
  336.     }
  337.  
  338.   INCREMENT_CONS_COUNTER (sizeof (struct extent_replica));
  339.  
  340.   return val;
  341. }
  342.  
  343.  
  344. #ifdef LISP_FLOAT_TYPE
  345. /* Allocation of float cells, just like conses */
  346. /* We store float cells inside of float_blocks, allocating a new
  347.    float_block with malloc whenever necessary.  Float cells reclaimed by
  348.    GC are put on a free list to be reallocated before allocating
  349.    any new float cells from the latest float_block.
  350.  
  351.    Each float_block is just under 1020 bytes long,
  352.    since malloc really allocates in units of powers of two
  353.    and uses 4 bytes for its own overhead. */
  354.  
  355. #define FLOAT_BLOCK_SIZE \
  356.   ((1020 - sizeof (struct float_block *)) / sizeof (struct Lisp_Float))
  357.  
  358. struct float_block
  359.   {
  360.     struct float_block *next;
  361.     struct Lisp_Float floats[FLOAT_BLOCK_SIZE];
  362.   };
  363.  
  364. static struct float_block *float_block;
  365. static int float_block_index;
  366.  
  367. struct Lisp_Float *float_free_list;
  368.  
  369. static void
  370. init_float ()
  371. {
  372.   float_block = (struct float_block *) xmalloc (sizeof (struct float_block));
  373.   float_block->next = 0;
  374.   memset (float_block->floats, 0, sizeof float_block->floats);
  375.   float_block_index = 0;
  376.   float_free_list = 0;
  377. }
  378.  
  379. /* Explicitly free a float cell.  */
  380. void
  381. free_float (ptr)
  382.      struct Lisp_Float *ptr;
  383. {
  384.   XFASTINT (ptr->type) = (int) float_free_list;
  385.   float_free_list = ptr;
  386. }
  387.  
  388. Lisp_Object
  389. make_float (float_value)
  390.      double float_value;
  391. {
  392.   register Lisp_Object val;
  393.  
  394.   if (float_free_list)
  395.     {
  396.       XSET (val, Lisp_Float, float_free_list);
  397.       float_free_list = (struct Lisp_Float *) XFASTINT (float_free_list->type);
  398.     }
  399.   else
  400.     {
  401.       if (float_block_index == FLOAT_BLOCK_SIZE)
  402.     {
  403.       register struct float_block *new =
  404.         (struct float_block *) xmalloc (sizeof (struct float_block));
  405.       if (!new) memory_full ();
  406.       VALIDATE_LISP_STORAGE (new, sizeof *new);
  407.       new->next = float_block;
  408.       float_block = new;
  409.       float_block_index = 0;
  410.     }
  411.       XSET (val, Lisp_Float, &float_block->floats[float_block_index++]);
  412.     }
  413.   XFLOAT (val)->data = float_value;
  414.   XFLOAT (val)->type = 0;    /* bug chasing -wsr */
  415.   INCREMENT_CONS_COUNTER (sizeof (struct Lisp_Float));
  416.   return val;
  417. }
  418.  
  419. #endif /* LISP_FLOAT_TYPE */
  420.  
  421. /* Allocation of cons cells */
  422. /* We store cons cells inside of cons_blocks, allocating a new
  423.    cons_block with malloc whenever necessary.  Cons cells reclaimed by
  424.    GC are put on a free list to be reallocated before allocating
  425.    any new cons cells from the latest cons_block.
  426.  
  427.    Each cons_block is just under 1020 bytes long,
  428.    since malloc really allocates in units of powers of two
  429.    and uses 4 bytes for its own overhead. */
  430.  
  431. #define CONS_BLOCK_SIZE \
  432.   ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons))
  433.  
  434. struct cons_block
  435.   {
  436.     struct cons_block *next;
  437.     struct Lisp_Cons conses[CONS_BLOCK_SIZE];
  438.   };
  439.  
  440. static struct cons_block *cons_block;
  441. static int cons_block_index;
  442.  
  443. static struct Lisp_Cons *cons_free_list;
  444.  
  445. static void
  446. init_cons ()
  447. {
  448.   cons_block = (struct cons_block *) xmalloc (sizeof (struct cons_block));
  449.   cons_block->next = 0;
  450.   memset (cons_block->conses, 0, sizeof cons_block->conses);
  451.   cons_block_index = 0;
  452.   cons_free_list = 0;
  453. }
  454.  
  455. /* Explicitly free a cons cell.  */
  456. void
  457. free_cons (ptr)
  458.      struct Lisp_Cons *ptr;
  459. {
  460.   XFASTINT (ptr->car) = (int) cons_free_list;
  461.   cons_free_list = ptr;
  462. }
  463.  
  464. DEFUN ("cons", Fcons, Scons, 2, 2, 0,
  465.   "Create a new cons, give it CAR and CDR as components, and return it.")
  466.   (car, cdr)
  467.      Lisp_Object car, cdr;
  468. {
  469.   register Lisp_Object val;
  470.  
  471.   if (cons_free_list)
  472.     {
  473.       XSET (val, Lisp_Cons, cons_free_list);
  474.       cons_free_list = (struct Lisp_Cons *) XFASTINT (cons_free_list->car);
  475.     }
  476.   else
  477.     {
  478.       if (cons_block_index == CONS_BLOCK_SIZE)
  479.     {
  480.       register struct cons_block *new =
  481.         (struct cons_block *) xmalloc (sizeof (struct cons_block));
  482.       if (!new) memory_full ();
  483.       VALIDATE_LISP_STORAGE (new, sizeof *new);
  484.       new->next = cons_block;
  485.       cons_block = new;
  486.       cons_block_index = 0;
  487.     }
  488.       XSET (val, Lisp_Cons, &cons_block->conses[cons_block_index++]);
  489.     }
  490.   XCONS (val)->car = car;
  491.   XCONS (val)->cdr = cdr;
  492.   INCREMENT_CONS_COUNTER (sizeof (struct Lisp_Cons));
  493.   return val;
  494. }
  495.  
  496. DEFUN ("list", Flist, Slist, 0, MANY, 0,
  497.   "Return a newly created list with specified arguments as elements.\n\
  498. Any number of arguments, even zero arguments, are allowed.")
  499.   (nargs, args)
  500.      int nargs;
  501.      register Lisp_Object *args;
  502. {
  503.   register Lisp_Object len, val, val_tail;
  504.  
  505.   XFASTINT (len) = nargs;
  506.   val = Fmake_list (len, Qnil);
  507.   val_tail = val;
  508.   while (!NILP (val_tail))
  509.     {
  510.       XCONS (val_tail)->car = *args++;
  511.       val_tail = XCONS (val_tail)->cdr;
  512.     }
  513.   return val;
  514. }
  515.  
  516. Lisp_Object
  517. list1 (Lisp_Object obj0)
  518. {
  519.   return (Fcons (obj0, Qnil));
  520. }
  521.  
  522. Lisp_Object
  523. list2 (Lisp_Object obj0, Lisp_Object obj1)
  524. {
  525.   return Fcons (obj0, list1 (obj1));
  526. }
  527.  
  528. Lisp_Object
  529. list3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2)
  530. {
  531.   return Fcons (obj0, list2 (obj1, obj2));
  532. }
  533.  
  534. Lisp_Object
  535. list4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3)
  536. {
  537.   return Fcons (obj0, list3 (obj1, obj2, obj3));
  538. }
  539.  
  540. Lisp_Object
  541. list5 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3,
  542.        Lisp_Object obj4)
  543. {
  544.   return Fcons (obj0, list4 (obj1, obj2, obj3, obj4));
  545. }
  546.  
  547. DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
  548.   "Return a newly created list of length LENGTH, with each element being INIT.")
  549.   (length, init)
  550.      register Lisp_Object length, init;
  551. {
  552.   register Lisp_Object val;
  553.   register int size;
  554.  
  555.   if (!FIXNUMP (length) || XINT (length) < 0)
  556.     length = wrong_type_argument (Qnatnump, length);
  557.   size = XINT (length);
  558.  
  559.   val = Qnil;
  560.   while (size-- > 0)
  561.     val = Fcons (init, val);
  562.   return val;
  563. }
  564.  
  565. /* Allocation of vectors */
  566.  
  567. static struct Lisp_Vector *all_vectors;
  568.  
  569. DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
  570.   "Return a newly created vector of length LENGTH, with each element being INIT.\n\
  571. See also the function `vector'.")
  572.   (length, init)
  573.      register Lisp_Object length, init;
  574. {
  575.   register int sizei, index;
  576.   register Lisp_Object vector;
  577.   register struct Lisp_Vector *p;
  578.  
  579.   if (!FIXNUMP (length) || XINT (length) < 0)
  580.     length = wrong_type_argument (Qnatnump, length);
  581.   sizei = XINT (length);
  582.  
  583.   p = (struct Lisp_Vector *)
  584.     xmalloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object));
  585.   if (p == 0)
  586.     memory_full ();
  587.   VALIDATE_LISP_STORAGE (p, 0);
  588.  
  589.   XSET (vector, Lisp_Vector, p);
  590.   INCREMENT_CONS_COUNTER 
  591.     (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object));
  592.  
  593.   p->size = sizei;
  594.   p->next = all_vectors;
  595.   all_vectors = p;
  596.  
  597.   for (index = 0; index < sizei; index++)
  598.     p->contents[index] = init;
  599.  
  600.   return vector;
  601. }
  602.  
  603. DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
  604.   "Return a newly created vector with specified arguments as elements.\n\
  605. Any number of arguments, even zero arguments, are allowed.")
  606.   (nargs, args)
  607.      register int nargs;
  608.      Lisp_Object *args;
  609. {
  610.   register Lisp_Object len, val;
  611.   register int index;
  612.   register struct Lisp_Vector *p;
  613.  
  614.   XFASTINT (len) = nargs;
  615.   val = Fmake_vector (len, Qnil);
  616.   p = XVECTOR (val);
  617.   for (index = 0; index < nargs; index++)
  618.     p->contents[index] = args[index];
  619.   return val;
  620. }
  621.  
  622. DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0,
  623.   "Create a byte-code object with specified arguments as elements.\n\
  624. At least four arguments are required; only six have any significance.")
  625.   (nargs, args)
  626.      register int nargs;
  627.      Lisp_Object *args;
  628. {
  629.   register Lisp_Object len, val;
  630.   register int index;
  631.   register struct Lisp_Vector *p;
  632.  
  633.   XFASTINT (len) = nargs;
  634.   if (!NILP (Vpurify_flag))
  635.     val = make_pure_vector (len, Lisp_Compiled);
  636.   else
  637.     {
  638.       val = Fmake_vector (len, Qnil);
  639.       XSETTYPE (val, Lisp_Compiled);
  640.     }
  641.   p = XVECTOR (val);
  642.   for (index = 0; index < nargs; index++)
  643.     {
  644.       if (!NILP (Vpurify_flag))
  645.     args[index] = Fpurecopy (args[index]);
  646.       p->contents[index] = args[index];
  647.     }
  648.   return val;
  649. }
  650.  
  651. /* Allocation of symbols.
  652.    Just like allocation of conses!
  653.  
  654.    Each symbol_block is just under 1020 bytes long,
  655.    since malloc really allocates in units of powers of two
  656.    and uses 4 bytes for its own overhead. */
  657.  
  658. #define SYMBOL_BLOCK_SIZE \
  659.   ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
  660.  
  661. struct symbol_block
  662.   {
  663.     struct symbol_block *next;
  664.     struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
  665.   };
  666.  
  667. static struct symbol_block *symbol_block;
  668. static int symbol_block_index;
  669.  
  670. static struct Lisp_Symbol *symbol_free_list;
  671.  
  672. static void
  673. init_symbol ()
  674. {
  675.   symbol_block =
  676.     (struct symbol_block *) xmalloc (sizeof (struct symbol_block));
  677.   symbol_block->next = 0;
  678.   memset (symbol_block->symbols, 0, sizeof symbol_block->symbols);
  679.   symbol_block_index = 0;
  680.   symbol_free_list = 0;
  681. }
  682.  
  683. DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
  684.   "Return a newly allocated uninterned symbol whose name is NAME.\n\
  685. Its value and function definition are void, and its property list is nil.")
  686.   (str)
  687.      Lisp_Object str;
  688. {
  689.   register Lisp_Object val;
  690.   register struct Lisp_Symbol *p;
  691.  
  692.   CHECK_STRING (str, 0);
  693.  
  694.   if (symbol_free_list)
  695.     {
  696.       XSET (val, Lisp_Symbol, symbol_free_list);
  697.       symbol_free_list
  698.     = (struct Lisp_Symbol *) XFASTINT (symbol_free_list->value);
  699.     }
  700.   else
  701.     {
  702.       if (symbol_block_index == SYMBOL_BLOCK_SIZE)
  703.     {
  704.       struct symbol_block *new =
  705.         (struct symbol_block *) xmalloc (sizeof (struct symbol_block));
  706.       if (!new) memory_full ();
  707.       new->next = symbol_block;
  708.       VALIDATE_LISP_STORAGE (new, sizeof *new);
  709.       symbol_block = new;
  710.       symbol_block_index = 0;
  711.     }
  712.       XSET (val, Lisp_Symbol, &symbol_block->symbols[symbol_block_index++]);
  713.     }
  714.   p = XSYMBOL (val);
  715.   p->name = XSTRING (str);
  716.   p->plist = Qnil;
  717.   p->value = Qunbound;
  718.   p->function = Qunbound;
  719.   p->next = 0;
  720.   INCREMENT_CONS_COUNTER (sizeof (struct Lisp_Symbol));
  721.   return val;
  722. }
  723.  
  724. /* Allocation of markers.
  725.    Works like allocation of conses. */
  726.  
  727. #define MARKER_BLOCK_SIZE \
  728.   ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker))
  729.  
  730. struct marker_block
  731.   {
  732.     struct marker_block *next;
  733.     struct Lisp_Marker markers[MARKER_BLOCK_SIZE];
  734.   };
  735.  
  736. static struct marker_block *marker_block;
  737. static int marker_block_index;
  738.  
  739. static struct Lisp_Marker *marker_free_list;
  740.  
  741. static void
  742. init_marker ()
  743. {
  744.   marker_block = (struct marker_block *)
  745.     xmalloc (sizeof (struct marker_block));
  746.   marker_block->next = 0;
  747.   memset (marker_block->markers, 0, sizeof marker_block->markers);
  748.   marker_block_index = 0;
  749.   marker_free_list = 0;
  750. }
  751.  
  752. DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
  753.   "Return a newly allocated marker which does not point at any place.")
  754.   ()
  755. {
  756.   register Lisp_Object val;
  757.   register struct Lisp_Marker *p;
  758.  
  759.   if (marker_free_list)
  760.     {
  761.       XSET (val, Lisp_Marker, marker_free_list);
  762.       marker_free_list
  763.     = (struct Lisp_Marker *) XFASTINT (marker_free_list->chain);
  764.     }
  765.   else
  766.     {
  767.       if (marker_block_index == MARKER_BLOCK_SIZE)
  768.     {
  769.       struct marker_block *new =
  770.         (struct marker_block *) xmalloc (sizeof (struct marker_block));
  771.       if (!new) memory_full ();
  772.       VALIDATE_LISP_STORAGE (new, sizeof *new);
  773.       new->next = marker_block;
  774.       marker_block = new;
  775.       marker_block_index = 0;
  776.     }
  777.       XSET (val, Lisp_Marker, &marker_block->markers[marker_block_index++]);
  778.     }
  779.   p = XMARKER (val);
  780.   p->buffer = 0;
  781.   p->bufpos = 0;
  782.   p->chain = Qnil;
  783.   INCREMENT_CONS_COUNTER (sizeof (struct Lisp_Marker));
  784.   return val;
  785. }
  786.  
  787. /* Allocation of strings */
  788.  
  789. /* The data for "short" strings generally resides inside of structs of type 
  790.    string_chars_block. The Lisp_String structure is allocated just like any 
  791.    other Lisp object (except for vectors), and these are freelisted when
  792.    the get garbage collected. The data for short strings get compacted,
  793.    but the data for large strings do not. 
  794.  
  795.    Previously Lisp_String structures were relocated, but this caused a lot
  796.    of bus-errors because the C code didn't include enough GCPRO's for
  797.    strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
  798.    that the reference would get relocated).
  799.  
  800.    This new method makes things somewhat bigger, but it is MUCH safer.  */
  801.  
  802.  
  803. /* If SIZE is the length of a string, this returns how many bytes
  804.    the string occupies in a string_chars_block (including padding).  */
  805. #define PAD ((sizeof (struct Lisp_String *)) - 1)
  806. #define ROUND_UP_STRING_SIZE(s) (((s) + 1 + PAD) & ~PAD)
  807. #define STRING_FULLSIZE(size) \
  808. ROUND_UP_STRING_SIZE ((size) + sizeof (struct Lisp_String *))
  809.  
  810. #define STRING_BLOCK_SIZE \
  811. ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String))
  812. /* String blocks contain this many useful bytes.
  813.    8188 is power of 2, minus 4 for malloc overhead. */
  814. #define STRING_CHARS_BLOCK_SIZE \
  815. (8188 - ((2 * sizeof (struct string_chars_block *))+ sizeof (int)))
  816.  
  817. struct string_chars
  818. {
  819.   struct Lisp_String *string;
  820.   unsigned char chars[1];
  821. };
  822.  
  823. #define SLOT_OFFSET(type, slot_name) \
  824. ((unsigned) (((char *) (&(((type *)0)->slot_name))) - ((char *) 0)))
  825. #define CHARS_TO_STRING_CHAR(x) \
  826. ((struct string_chars *)\
  827.  (((char *) (x)) - (SLOT_OFFSET(struct string_chars, chars))))
  828.  
  829. /* Block header for small strings. */
  830. struct string_chars_block
  831. {
  832.   struct string_chars_block *next;
  833.   struct string_chars_block *prev;
  834.   int pos;
  835.   unsigned char chars[STRING_CHARS_BLOCK_SIZE];
  836. };
  837.  
  838. struct string_block
  839. {
  840.   struct string_block *next;
  841.   struct Lisp_String strings[STRING_BLOCK_SIZE];
  842. };
  843.  
  844. static struct string_block *string_block;
  845. static int string_block_index;
  846. static struct Lisp_String *string_free_list;
  847.  
  848. static struct string_chars_block *current_string_chars_block;
  849. static struct string_chars_block *first_string_chars_block;
  850.  
  851. #define NONRELOCATING_STRING_SIZE(size) ((size) >= 1020)
  852. #define BIG_STRING_SIZE(size) (NONRELOCATING_STRING_SIZE(size))
  853.  
  854. static void
  855. init_strings ()
  856. {
  857.   string_block =
  858.     (struct string_block *) xmalloc (sizeof (struct string_block));
  859.   string_block->next = 0;
  860.   memset (string_block->strings, 0, sizeof string_block->strings);
  861.   string_block_index = 0;
  862.   string_free_list = 0;
  863.  
  864.   first_string_chars_block = 
  865.     (struct string_chars_block *) xmalloc (sizeof (struct string_chars_block));
  866.   current_string_chars_block = first_string_chars_block;
  867.   current_string_chars_block->prev = 0;
  868.   current_string_chars_block->next = 0;
  869.   current_string_chars_block->pos = 0;
  870. }
  871.  
  872. static struct Lisp_String *
  873. make_string_internal ()
  874. {
  875.   struct Lisp_String *val;
  876.  
  877.   if (string_free_list)
  878.     {
  879.       val = string_free_list;
  880.       string_free_list = (struct Lisp_String *)string_free_list->dup_list;
  881.       val->dup_list = 0;
  882.     }
  883.   else
  884.     {
  885.       if (string_block_index == STRING_BLOCK_SIZE)
  886.     {
  887.       struct string_block *new_sb
  888.         = (struct string_block *) xmalloc (sizeof (struct string_block));
  889.  
  890.       if (!new_sb)
  891.         memory_full ();
  892.  
  893.           memset ((char *) new_sb, 0, sizeof (struct string_block));
  894.  
  895.       VALIDATE_LISP_STORAGE (new_sb, sizeof *new_sb);
  896.       new_sb->next = string_block;
  897.       string_block = new_sb;
  898.       string_block_index = 0;
  899.     }
  900.       val = &string_block->strings[string_block_index++];
  901.     }
  902.  
  903.   return val;
  904. }
  905.  
  906.  
  907. static struct string_chars *
  908. allocate_string_chars (size, fullsize)
  909.      int size;
  910.      int fullsize;
  911. {
  912.   struct string_chars *s_chars;
  913.   
  914.   if (BIG_STRING_SIZE (size))
  915.     {
  916.       s_chars = (struct string_chars *) xmalloc (fullsize);
  917.       if (!s_chars)
  918.     memory_full ();
  919.     }
  920.   else if (fullsize <=
  921.            (STRING_CHARS_BLOCK_SIZE - current_string_chars_block->pos))
  922.     {
  923.       /* This string can fit in the current string chars block */
  924.       s_chars = 
  925.         (struct string_chars *) 
  926.           (current_string_chars_block->chars + 
  927.            current_string_chars_block->pos);
  928.       current_string_chars_block->pos += fullsize;
  929.     }
  930.   else
  931.     {
  932.       /* Make a new current string chars block */
  933.       struct string_chars_block *new = 
  934.         (struct string_chars_block *) 
  935.           xmalloc (sizeof (struct string_chars_block));
  936.       if (!new)
  937.     memory_full ();
  938.  
  939.       current_string_chars_block->next = new;
  940.       new->prev = current_string_chars_block;
  941.       new->next = 0;
  942.       current_string_chars_block = new;
  943.       new->pos = fullsize;
  944.       s_chars = (struct string_chars *) current_string_chars_block->chars;
  945.     }
  946.  
  947.   return s_chars;
  948. }
  949.  
  950.  
  951. static Lisp_Object
  952. make_uninit_string (length)
  953.      int length;
  954. {
  955.   struct Lisp_String *string;
  956.   struct string_chars *s_chars;
  957.   Lisp_Object val;
  958.   int fullsize = STRING_FULLSIZE (length);
  959.  
  960.   if ((length < 0) || (fullsize <= 0))
  961.     abort ();
  962.  
  963.   string = make_string_internal();
  964.   s_chars = allocate_string_chars (length, fullsize);
  965.   s_chars->string = string;
  966.  
  967.   string->size = length;
  968.   string->data = &(s_chars->chars[0]);
  969.   string->dup_list = Qnil;
  970.  
  971.   string->data[length] = 0;
  972.  
  973.   XSET (val, Lisp_String, string);
  974.  
  975.   INCREMENT_CONS_COUNTER (sizeof (struct Lisp_String) + fullsize);
  976.   return val;
  977. }
  978.  
  979. DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0,
  980.   "Return a newly created string of length LENGTH, with each element being INIT.\n\
  981. Both LENGTH and INIT must be numbers.")
  982.   (length, init)
  983.      Lisp_Object length, init;
  984. {
  985.   register Lisp_Object val;
  986.   register unsigned char *p, *end, c;
  987.  
  988.   if (!FIXNUMP (length) || XINT (length) < 0)
  989.     length = wrong_type_argument (Qnatnump, length);
  990.   CHECK_FIXNUM (init, 1);
  991.   val = make_uninit_string (XINT (length));
  992.   c = XINT (init);
  993.   p = XSTRING (val)->data;
  994.   end = p + XSTRING (val)->size;
  995.   while (p < end)
  996.     *p++ = c;
  997.   return val;
  998. }
  999.  
  1000. extern void move_gap (int);
  1001.  
  1002. Lisp_Object
  1003. make_string_from_buffer (buf, index, length)
  1004.      struct buffer *buf;
  1005.      int index, length;
  1006. {
  1007.   Lisp_Object val = make_uninit_string (length);
  1008.  
  1009.   XSTRING (val)->dup_list = replicate_extents (index, length, buf);
  1010.  
  1011.   if (index < BUF_GPT (buf) && index + length > BUF_GPT (buf))
  1012.     move_gap (index);
  1013.   memcpy (XSTRING (val)->data, BUF_CHAR_ADDRESS (buf, index), length);
  1014.   return val;
  1015. }
  1016.  
  1017. Lisp_Object
  1018. make_string (contents, length)
  1019.      const char *contents;
  1020.      int length;
  1021. {
  1022.   register Lisp_Object val;
  1023.   val = make_uninit_string (length);
  1024.   memcpy (XSTRING (val)->data, contents, length);
  1025.   return val;
  1026. }
  1027.  
  1028. Lisp_Object
  1029. build_string (str)
  1030.      const char *str;
  1031. {
  1032.   return make_string (str, strlen (str));
  1033. }
  1034.  
  1035.  
  1036. /* Must get an error if pure storage is full,
  1037.  since if it cannot hold a large string
  1038.  it may be able to hold conses that point to that string;
  1039.  then the string is not protected from gc. */
  1040.  
  1041. #ifdef PURESTAT
  1042. static Lisp_Object
  1043. make_pure_string_1 (const char *data, int length, int purestat_index)
  1044. #else
  1045. Lisp_Object
  1046. make_pure_string (const char *data, int length)
  1047. #endif
  1048. {
  1049.   Lisp_Object new;
  1050.   unsigned char *chars;
  1051.   int size = sizeof (struct Lisp_String) + ROUND_UP_STRING_SIZE (length);
  1052.  
  1053.   if (pureptr + size > PURESIZE)
  1054.     pure_storage_exhausted ();
  1055.  
  1056.   XSET (new, Lisp_String, PUREBEG + pureptr);
  1057.   chars = (unsigned char *) (PUREBEG + pureptr + sizeof (struct Lisp_String));
  1058.   XSTRING (new)->size = length;
  1059.   XSTRING (new)->data = chars;
  1060.   memcpy (XSTRING (new)->data, data, length);
  1061.   XSTRING (new)->data[length] = 0;
  1062.   XSTRING (new)->dup_list = Qnil;
  1063.   pureptr += ((size + sizeof (int) - 1) / sizeof (int)) * sizeof (int);
  1064. #ifdef PURESTAT
  1065.   purestat [0][purestat_index]++;
  1066.   purestat [1][purestat_index] +=
  1067.     ((size + sizeof (int) - 1) / sizeof (int)) * sizeof (int);
  1068. #endif
  1069.   return new;
  1070. }
  1071.  
  1072. #ifdef PURESTAT
  1073. Lisp_Object
  1074. make_pure_string (const char *data, int length)
  1075. {
  1076.   return make_pure_string_1 (data, length, 1);
  1077. }
  1078. #endif
  1079.  
  1080. Lisp_Object
  1081. make_pure_symbol_name (data, length)
  1082.      const char *data;
  1083.      int length;
  1084. {
  1085. #ifdef PURESTAT
  1086.   return make_pure_string_1 (data, length, 7);
  1087. #else
  1088.   return make_pure_string (data, length);
  1089. #endif
  1090. }
  1091.  
  1092.  
  1093. Lisp_Object
  1094. pure_cons (car, cdr)
  1095.      Lisp_Object car, cdr;
  1096. {
  1097.   register Lisp_Object new;
  1098.  
  1099.   if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE)
  1100.     pure_storage_exhausted ();
  1101.   XSET (new, Lisp_Cons, PUREBEG + pureptr);
  1102.   pureptr += sizeof (struct Lisp_Cons);
  1103.   XCONS (new)->car = Fpurecopy (car);
  1104.   XCONS (new)->cdr = Fpurecopy (cdr);
  1105. #ifdef PURESTAT
  1106.   purestat [0][0]++;
  1107.   purestat [1][0] += sizeof (struct Lisp_Cons);
  1108. #endif
  1109.   return new;
  1110. }
  1111.  
  1112. #ifdef LISP_FLOAT_TYPE
  1113.  
  1114. static Lisp_Object
  1115. make_pure_float (num)
  1116.      double num;
  1117. {
  1118.   register Lisp_Object new;
  1119.  
  1120.   /* pure_floats have to be double aligned. */
  1121.   pureptr = (pureptr + 0x7) & ~0x7;
  1122.  
  1123.   if (pureptr + sizeof (struct Lisp_Float) > PURESIZE)
  1124.     pure_storage_exhausted ();
  1125.   XSET (new, Lisp_Float, PUREBEG + pureptr);
  1126.   pureptr += sizeof (struct Lisp_Float);
  1127.   XFLOAT (new)->data = num;
  1128.   XFLOAT (new)->type = 0;    /* bug chasing -wsr */
  1129. #ifdef PURESTAT
  1130.   purestat [0][4]++;
  1131.   purestat [1][4] += sizeof (struct Lisp_Float);
  1132. #endif
  1133.   return new;
  1134. }
  1135.  
  1136. #endif /* LISP_FLOAT_TYPE */
  1137.  
  1138. Lisp_Object
  1139. make_pure_vector (len, vector_type)
  1140.      int len;
  1141.      enum Lisp_Type vector_type;
  1142. {
  1143.   register Lisp_Object new;
  1144.   register int size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object);
  1145.  
  1146.   if (pureptr + size > PURESIZE)
  1147.     pure_storage_exhausted ();
  1148.   XSET (new, Lisp_Vector, PUREBEG + pureptr);
  1149.   pureptr += size;
  1150.   XVECTOR (new)->size = len;
  1151.  
  1152. #ifdef PURESTAT
  1153.   {
  1154.     int i = (vector_type == Lisp_Compiled ? 3
  1155.          : (vector_type == 0 ? 6 : 2));
  1156.     purestat [0][i]++;
  1157.     purestat [1][i] += size;
  1158.     if (vector_type == 0) /* kludge kludge kludge */
  1159.       vector_type = Lisp_Vector;
  1160.   }
  1161. #endif
  1162.  
  1163.   XSETTYPE (new, vector_type);
  1164.   return new;
  1165. }
  1166.  
  1167. #ifdef PURESTAT
  1168. static int copying_function_object;
  1169. #endif
  1170.  
  1171. DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
  1172.   "Make a copy of OBJECT in pure storage.\n\
  1173. Recursively copies contents of vectors and cons cells.\n\
  1174. Does not copy symbols.")
  1175.   (obj)
  1176.      register Lisp_Object obj;
  1177. {
  1178.   register Lisp_Object new, tem;
  1179.   register int i;
  1180.   int fn_p = 0;
  1181.  
  1182.   if (NILP (Vpurify_flag))
  1183.     return obj;
  1184.  
  1185.   if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)
  1186.       && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure)
  1187.     return obj;
  1188.  
  1189. #ifdef SWITCH_ENUM_BUG
  1190.   switch ((int) XTYPE (obj))
  1191. #else
  1192.   switch (XTYPE (obj))
  1193. #endif
  1194.     {
  1195.     case Lisp_Marker:
  1196.       error ("Attempt to copy a marker to pure storage");
  1197.  
  1198.     case Lisp_Cons:
  1199.       return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr);
  1200.  
  1201. #ifdef LISP_FLOAT_TYPE
  1202.     case Lisp_Float:
  1203.       return make_pure_float (XFLOAT (obj)->data);
  1204. #endif /* LISP_FLOAT_TYPE */
  1205.  
  1206.     case Lisp_String:
  1207. #ifdef PURESTAT
  1208.       if (copying_function_object)
  1209.     return make_pure_string_1 ((char *) XSTRING (obj)->data,
  1210.                    XSTRING (obj)->size, 10);
  1211. #endif
  1212.       return make_pure_string ((char *) XSTRING (obj)->data,
  1213.                    XSTRING (obj)->size);
  1214.  
  1215.     case Lisp_Compiled:
  1216.       fn_p = 1;
  1217.     case Lisp_Vector:
  1218.       new = make_pure_vector (XVECTOR (obj)->size, XTYPE (obj));
  1219.       for (i = 0; i < XVECTOR (obj)->size; i++)
  1220.     {
  1221.       tem = XVECTOR (obj)->contents[i];
  1222. #ifdef PURESTAT
  1223.       /* do separate recording for the code strings, data vectors,
  1224.          doc strings, and interactive specs.
  1225.        */
  1226.       if (fn_p) copying_function_object++;
  1227.       if (fn_p && i == 1 && STRINGP (tem))        /* byte code */
  1228.         XVECTOR (new)->contents[i] =
  1229.           make_pure_string_1 ((char *) XSTRING (tem)->data,
  1230.                   XSTRING (tem)->size, 5);
  1231.       else if (fn_p && i == 2 && VECTORP (tem))    /* constants */
  1232.         {
  1233.           int j;
  1234.           Lisp_Object v2 = XVECTOR (new)->contents[i] =
  1235.         make_pure_vector (XVECTOR (tem)->size, 0);
  1236.           for (j = 0; j < XVECTOR (tem)->size; j++)
  1237.         XVECTOR (v2)->contents[j] =
  1238.           Fpurecopy (XVECTOR (tem)->contents[j]);
  1239.         }
  1240.       else if (fn_p && i == 4 && STRINGP (tem))    /* doc string */
  1241.         XVECTOR (new)->contents[i] =
  1242.           make_pure_string_1 ((char *) XSTRING (tem)->data,
  1243.                   XSTRING (tem)->size, 8);
  1244.       else if (fn_p && i == 5 && STRINGP (tem))    /* interactive spec */
  1245.         XVECTOR (new)->contents[i] =
  1246.           make_pure_string_1 ((char *) XSTRING (tem)->data,
  1247.                   XSTRING (tem)->size, 9);
  1248.       else
  1249. #endif
  1250.       XVECTOR (new)->contents[i] = Fpurecopy (tem);
  1251.     }
  1252.       if (fn_p)
  1253.     {
  1254.       XSETTYPE (new, Lisp_Compiled);
  1255. #ifdef PURESTAT
  1256.       copying_function_object--;
  1257. #endif
  1258.     }
  1259.       return new;
  1260.  
  1261.     default:
  1262.       return obj;
  1263.     }
  1264. }
  1265.  
  1266. void 
  1267. report_pure_usage ()
  1268. {
  1269.   printf ("purespace usage: %d of %d (%d%%).\n",
  1270.       pureptr, PURESIZE, pureptr / (PURESIZE / 100));
  1271. #ifdef PURESTAT
  1272. # define P(s,i) \
  1273.   printf (s, purestat[0][i], purestat[1][i], purestat[1][i] / (pureptr / 100))
  1274.   printf ("                           total:   bytes:\n");
  1275.   P("   cons cells:             %5d  %7d  %2d%%\n", 0);
  1276. #ifdef LISP_FLOAT_TYPE
  1277.   P("   float objects:          %5d  %7d  %2d%%\n", 4);
  1278. #endif
  1279.   P("   symbol-name strings:    %5d  %7d  %2d%%\n", 7);
  1280.   P("   function objects:       %5d  %7d  %2d%%\n", 3);
  1281.   P("   byte-code strings:      %5d  %7d  %2d%%\n", 5);
  1282.   P("   byte-constant vectors:  %5d  %7d  %2d%%\n", 6);
  1283.   P("   interactive strings:    %5d  %7d  %2d%%\n", 9);
  1284.   P("   documentation strings:  %5d  %7d  %2d%%\n", 8);
  1285.   P("   other function strings: %5d  %7d  %2d%%\n", 10);
  1286.   P("   other vectors:          %5d  %7d  %2d%%\n", 2);
  1287.   P("   other strings:          %5d  %7d  %2d%%\n", 1);
  1288. # undef P
  1289. #endif /* PURESTAT */
  1290. }
  1291.  
  1292. static void
  1293. pure_storage_exhausted ()
  1294. {
  1295.   fprintf (stderr, "\nERROR:  Pure Lisp storage exhausted!\n\
  1296. \tCheck whether you are loading .el files when .elc files were intended.\n\
  1297. \tOtherwise, increase PURESIZE in puresize.h and relink.\n\n");
  1298.   report_pure_usage ();
  1299.   Vpurify_flag = Qnil;
  1300.   Fkill_emacs (make_number (-1));
  1301. }
  1302.  
  1303. /* Recording what needs to be marked for gc.  */
  1304.  
  1305. struct gcpro *gcprolist;
  1306.  
  1307. #define NSTATICS 512
  1308.  
  1309. static Lisp_Object *staticvec[NSTATICS] = {0};
  1310.  
  1311. static int staticidx = 0;
  1312.  
  1313. /* Put an entry in staticvec, pointing at the variable whose address is given */
  1314.  
  1315. void
  1316. staticpro (varaddress)
  1317.      Lisp_Object *varaddress;
  1318. {
  1319.   staticvec[staticidx++] = varaddress;
  1320.   if (staticidx >= NSTATICS)
  1321.     abort ();
  1322. }
  1323.  
  1324. /* Flags are set during GC in the `size' component of a string or vector.
  1325.    On some machines, these flags are defined by the m- file to use
  1326.    different bits.
  1327.  
  1328.    On vectors, the flag means the vector has been marked.
  1329.  
  1330.    On string size field or a reference to a string, the flag means
  1331.    there are more entries in the chain. */
  1332.  
  1333. #ifndef ARRAY_MARK_FLAG
  1334. #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
  1335. #endif /* no ARRAY_MARK_FLAG */
  1336.  
  1337. /* Any slot that is a Lisp_Object can point to a string
  1338.    and thus can be put on a string's reference-chain
  1339.    and thus may need to have its ARRAY_MARK_FLAG set.
  1340.    This includes the slots whose markbits are used to mark
  1341.    the containing objects.  */
  1342.  
  1343. #ifdef EMACS_BTL
  1344. void BTL_before_Fgarbage_collect_stub ()
  1345. {
  1346.   return;
  1347. }
  1348. #endif
  1349.  
  1350. #if ARRAY_MARK_FLAG == MARKBIT
  1351. you lose
  1352. #endif
  1353.  
  1354. static int total_conses, total_markers, total_symbols;
  1355. static int total_vector_size, total_string_size, total_strings;
  1356. static int total_short_strings;
  1357. static int total_free_strings, total_free_conses;
  1358. static int total_free_markers, total_free_symbols;
  1359.  
  1360. #ifdef LISP_FLOAT_TYPE
  1361. static int total_free_floats, total_floats;
  1362. #endif /* LISP_FLOAT_TYPE */
  1363.  
  1364. static int total_free_events, total_events;
  1365.  
  1366. static void mark_object (), mark_buffer ();
  1367. static void mark_event (), mark_command_event_queue ();
  1368. static void gc_sweep ();
  1369. static void compact_string_chars ();
  1370.  
  1371. /* Mark just one extent. */
  1372. static void
  1373. mark_one_extent (extent)
  1374.      EXTENT extent;
  1375. {
  1376.   if (!EXTENT_MARKED_P (extent))
  1377.     {
  1378.       MARK_EXTENT (extent);
  1379.       mark_object (&extent->buffer);
  1380.       mark_object (&extent->user_data);
  1381.     }
  1382. }
  1383.  
  1384. /* Mark a list of extents. */
  1385. static void
  1386. mark_extents (extent)
  1387.      EXTENT extent;
  1388. {
  1389.   if (!EXTENT_LIST_MARKED_P (extent))
  1390.     {
  1391.       EXTENT e = extent;
  1392.       while (e)
  1393.         {
  1394.       if (!EXTENT_MARKED_P (e))
  1395.         mark_one_extent (e);
  1396.       MARK_EXTENT_LIST (e);
  1397.       if (e == e->next) abort ();
  1398.           e = e->next;
  1399.         }
  1400.     }
  1401. }
  1402.  
  1403. static int total_free_extents, total_extents;
  1404. static int total_free_dups, total_dups;
  1405.  
  1406.  
  1407. #ifdef HAVE_X_WINDOWS
  1408. extern unsigned long current_pointer_shape;
  1409. extern int x_show_gc_cursor (struct screen *);
  1410. extern int x_show_normal_cursor (struct screen *);
  1411. #endif
  1412.  
  1413.  
  1414.  
  1415. /* Mark reference to a Lisp_Object.  If the object referred to has not been
  1416.    seen yet, recursively mark all the references contained in it. */
  1417.    
  1418. static void
  1419. mark_object (objptr)
  1420.      Lisp_Object *objptr;
  1421. {
  1422.   register Lisp_Object obj;
  1423.  
  1424.   obj = *objptr;
  1425.   XUNMARK (obj);
  1426.  
  1427.  loop:
  1428.  
  1429.   if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)
  1430.       && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure)
  1431.     return;
  1432. #ifdef SWITCH_ENUM_BUG
  1433.   switch ((int) XGCTYPE (obj))
  1434. #else
  1435.   switch (XGCTYPE (obj))
  1436. #endif
  1437.     {
  1438.     case Lisp_String:
  1439.       {
  1440.     struct Lisp_String *ptr = XSTRING (obj);
  1441.  
  1442.         if (!XMARKBIT (ptr->dup_list))
  1443.           {
  1444.             XMARK(ptr->dup_list);
  1445.             mark_object (&ptr->dup_list);
  1446.           }
  1447.       }
  1448.       break;
  1449.  
  1450.     case Lisp_Vector:
  1451.     case Lisp_Window:
  1452.     case Lisp_Process:
  1453.     case Lisp_Window_Configuration:
  1454.     case Lisp_Compiled:
  1455.       {
  1456.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  1457.     register int size = ptr->size;
  1458.     register int i;
  1459.  
  1460.     if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
  1461.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  1462.     for (i = 0; i < size; i++)     /* and then mark its elements */
  1463.       mark_object (&ptr->contents[i]);
  1464.       }
  1465.       break;
  1466.  
  1467.     case Lisp_Keymap:
  1468.       {
  1469.     register struct Lisp_Keymap *ptr = XKEYMAP (obj);
  1470.     register int size = ptr->size;
  1471.     if (size & ARRAY_MARK_FLAG) break; /* Already marked */
  1472.     ptr->size |= ARRAY_MARK_FLAG;      /* Else mark it */
  1473.                        /* and then mark its elements */
  1474.     mark_object (&ptr->parent);
  1475.     mark_object (&ptr->sub_maps_cache);
  1476.     mark_object (&ptr->table);
  1477.     mark_object (&ptr->inverse_table);
  1478.     mark_object (&ptr->name);
  1479.       }
  1480.       break;
  1481.  
  1482. #ifdef MULTI_SCREEN
  1483.     case Lisp_Screen:
  1484.       {
  1485.     register struct screen *ptr = XSCREEN (obj);
  1486.     register int size = ptr->size;
  1487.  
  1488.     if (size & ARRAY_MARK_FLAG)
  1489.       break;   /* Already marked */
  1490.  
  1491.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  1492.     mark_object (&ptr->name);
  1493.     mark_object (&ptr->root_window);
  1494.     mark_object (&ptr->selected_window);
  1495.     mark_object (&ptr->minibuffer_window);
  1496.     mark_object (&ptr->buffer_alist);
  1497.     mark_object (&ptr->param_alist);
  1498.     mark_object (&ptr->menubar_data);
  1499.     mark_object (&ptr->face_alist);
  1500.       }
  1501.       break;
  1502. #endif /* MULTI_SCREEN */
  1503.  
  1504.     case Lisp_Symbol:
  1505.       {
  1506.     register struct Lisp_Symbol *ptr = XSYMBOL (obj);
  1507.     struct Lisp_Symbol *ptrx;
  1508.  
  1509.     if (XMARKBIT (ptr->plist)) break;
  1510.     XMARK (ptr->plist);
  1511.     XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
  1512.     mark_object (&ptr->name);
  1513.     mark_object ((Lisp_Object *) &ptr->value);
  1514.     mark_object (&ptr->function);
  1515.     mark_object (&ptr->plist);
  1516.     ptr = ptr->next;
  1517.     if (ptr)
  1518.       {
  1519.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  1520.         XSET (obj, Lisp_Symbol, ptrx);
  1521.         goto loop;
  1522.       }
  1523.       }
  1524.       break;
  1525.  
  1526.     case Lisp_Marker:
  1527.       XMARK (XMARKER (obj)->chain);
  1528.       /*
  1529.      DO NOT mark thru the marker's chain.
  1530.      The buffer's markers chain does not preserve markers from gc;
  1531.      Instead, markers are removed from the chain when they are freed
  1532.      by gc.
  1533.       */
  1534.       break;
  1535.  
  1536.     case Lisp_Cons:
  1537.     case Lisp_Buffer_Local_Value:
  1538.     case Lisp_Some_Buffer_Local_Value:
  1539.       {
  1540.     register struct Lisp_Cons *ptr = XCONS (obj);
  1541.     if (XMARKBIT (ptr->car)) break;
  1542.     XMARK (ptr->car);
  1543.     mark_object (&ptr->car);
  1544.     objptr = &ptr->cdr;
  1545.     obj = ptr->cdr;
  1546.     goto loop;
  1547.       }
  1548.  
  1549. #ifdef LISP_FLOAT_TYPE
  1550.     case Lisp_Float:
  1551.       XMARK (XFLOAT (obj)->type);
  1552.       break;
  1553. #endif /* LISP_FLOAT_TYPE */
  1554.  
  1555.     case Lisp_Buffer:
  1556.       if (!XMARKBIT (XBUFFER (obj)->name))
  1557.     mark_buffer (obj);
  1558.       break;
  1559.  
  1560.     case Lisp_Extent:
  1561.       if (!EXTENT_MARKED_P (XEXTENT (obj)))
  1562.     mark_one_extent (XEXTENT (obj));
  1563.       break;
  1564.  
  1565.     case Lisp_Extent_Replica:
  1566.       if (!DUP_MARKED_P (XDUP (obj)))
  1567.         {
  1568.           MARK_DUP (XDUP (obj));
  1569.           mark_object (&(XDUP (obj)->extent));
  1570.         }
  1571.       break;
  1572.  
  1573.     case Lisp_Int:
  1574.     case Lisp_Void:
  1575.     case Lisp_Subr:
  1576.     case Lisp_Intfwd:
  1577.     case Lisp_Boolfwd:
  1578.     case Lisp_Objfwd:
  1579.     case Lisp_Buffer_Objfwd:
  1580.     case Lisp_Internal_Stream:
  1581.     /*
  1582.        Lisp_Buffer_Objfwd not done.
  1583.        All markable slots in current buffer marked anyway.
  1584.  
  1585.        Lisp_Objfwd not done.
  1586.        The places they point to are protected with staticpro.
  1587.     */
  1588.       break;
  1589.  
  1590.     case Lisp_Event:
  1591.       {
  1592.     struct Lisp_Event *ptr = XEVENT (obj);
  1593.     if (! XMARKBIT ((int) ptr->event_type))
  1594.       mark_event (ptr);
  1595.     break;
  1596.       }
  1597.  
  1598.     default:
  1599.       abort ();
  1600.     }
  1601. }
  1602.  
  1603. /* Mark the pointers in a buffer structure.  */
  1604.  
  1605. static void
  1606. mark_buffer (buffer)
  1607.      Lisp_Object buffer;
  1608. {
  1609.   register struct buffer *buf = XBUFFER (buffer);
  1610.  
  1611.   /* This is the buffer's markbit */
  1612.   mark_object (&buf->name);
  1613.   XMARK (buf->name);
  1614.  
  1615.   /* mark the extents attached to this string, if any */
  1616.   if (EXTENTP (buf->extents))
  1617.     {
  1618.       EXTENT ext = XEXTENT (buf->extents);
  1619.       if (!EXTENT_LIST_MARKED_P (ext))
  1620.     mark_extents (ext);
  1621.     }
  1622.   else if (!NILP (buf->extents) && buf->extents)
  1623.     mark_object (&buf->extents);
  1624.  
  1625. #undef MARKED_SLOT
  1626. #define MARKED_SLOT(x) mark_object(&(buf->x))
  1627. #include "bufslots.h"
  1628. }
  1629.  
  1630. /* Mark all pointers in an event object */
  1631.  
  1632. static void
  1633. mark_event (ptr)
  1634.      struct Lisp_Event *ptr;
  1635. {
  1636.   int type = ptr->event_type;
  1637.   XMARK (ptr->event_type);
  1638.   switch (type) {
  1639.   case key_press_event:
  1640.     mark_object (&ptr->event.key.key);
  1641.     break;
  1642.   case process_event:
  1643.     mark_object (&ptr->event.process.process);
  1644.     break;
  1645.   case timeout_event:
  1646.     mark_object (&ptr->event.timeout.function);
  1647.     mark_object (&ptr->event.timeout.object);
  1648.     break;
  1649.   case eval_event:
  1650.   case menu_event:
  1651.     mark_object (&ptr->event.eval.function);
  1652.     mark_object (&ptr->event.eval.object);
  1653.     break;
  1654.   case button_press_event:
  1655.   case button_release_event:
  1656.   case pointer_motion_event:
  1657.   case magic_event:
  1658.   case empty_event:
  1659.   case dead_event:
  1660.     break;
  1661.   default:
  1662.     abort ();
  1663.   }
  1664. }
  1665.  
  1666.   
  1667. /* Mark events waiting to be read */
  1668. static void
  1669. mark_command_event_queue ()
  1670. {
  1671.   struct Lisp_Event *event = command_event_queue->head;
  1672.   while (event) {
  1673.     mark_event (event);
  1674.     event = event->next;
  1675.   }
  1676. }
  1677.  
  1678. /* Find all structures not marked, and free them. */
  1679.  
  1680. extern void free_unmarked_events (void);
  1681. extern void prepare_to_gc_events (void);
  1682.  
  1683. static void
  1684. gc_sweep ()
  1685. {
  1686.   compact_string_chars ();
  1687.  
  1688.   /* Put all unmarked conses on free list */
  1689.   {
  1690.     register struct cons_block *cblk;
  1691.     register int lim = cons_block_index;
  1692.     register int num_free = 0, num_used = 0;
  1693.  
  1694.     cons_free_list = 0;
  1695.   
  1696.     for (cblk = cons_block; cblk; cblk = cblk->next)
  1697.       {
  1698.     register int i;
  1699.     for (i = 0; i < lim; i++)
  1700.       if (!XMARKBIT (cblk->conses[i].car))
  1701.         {
  1702.           XFASTINT (cblk->conses[i].car) = (int) cons_free_list;
  1703.           num_free++;
  1704.           cons_free_list = &cblk->conses[i];
  1705.         }
  1706.       else
  1707.         {
  1708.           num_used++;
  1709.           XUNMARK (cblk->conses[i].car);
  1710.         }
  1711.     lim = CONS_BLOCK_SIZE;
  1712.       }
  1713.     total_conses = num_used;
  1714.     total_free_conses = num_free;
  1715.   }
  1716.  
  1717. #ifdef LISP_FLOAT_TYPE
  1718.   /* Put all unmarked floats on free list */
  1719.   {
  1720.     register struct float_block *fblk;
  1721.     register int lim = float_block_index;
  1722.     register int num_free = 0, num_used = 0;
  1723.  
  1724.     float_free_list = 0;
  1725.   
  1726.     for (fblk = float_block; fblk; fblk = fblk->next)
  1727.       {
  1728.     register int i;
  1729.     for (i = 0; i < lim; i++)
  1730.       if (!XMARKBIT (fblk->floats[i].type))
  1731.         {
  1732.           XFASTINT (fblk->floats[i].type) = (int) float_free_list;
  1733.           num_free++;
  1734.           float_free_list = &fblk->floats[i];
  1735.         }
  1736.       else
  1737.         {
  1738.           num_used++;
  1739.           XUNMARK (fblk->floats[i].type);
  1740.         }
  1741.     lim = FLOAT_BLOCK_SIZE;
  1742.       }
  1743.     total_floats = num_used;
  1744.     total_free_floats = num_free;
  1745.   }
  1746. #endif /* LISP_FLOAT_TYPE */
  1747.  
  1748.   /* Put all unmarked extents on free list */
  1749.   {
  1750.     register struct extent_block *eblk;
  1751.     register int lim = extent_block_index;
  1752.     register int num_free = 0, num_used = 0;
  1753.  
  1754.     extent_free_list = 0;
  1755.  
  1756.     for (eblk = extent_block; eblk; eblk = eblk->next)
  1757.       {
  1758.     register int i;
  1759.  
  1760.     for (i = 0; i < lim; i++)
  1761.       {
  1762.             EXTENT extent = &(eblk->extents[i]);
  1763.         if (!EXTENT_MARKED_P (extent))
  1764.           {
  1765.                 memset ((char *) extent, 0, sizeof (struct extent));
  1766.         extent->user_data = Qnil;
  1767.         extent->next = extent_free_list;
  1768.         extent_free_list = extent;
  1769. #ifdef ENERGIZE
  1770.                 {
  1771.                   extern void energize_extent_finalization ();
  1772.                   energize_extent_finalization (extent);
  1773.                 }
  1774. #endif
  1775.         num_free++;
  1776.           }
  1777.         else
  1778.           {
  1779.         num_used++;
  1780.         UNMARK_EXTENT (extent);
  1781.           }
  1782.       }
  1783.     lim = EXTENT_BLOCK_SIZE;
  1784.       }
  1785.     total_extents = num_used;
  1786.     total_free_extents = num_free;
  1787.   }
  1788.  
  1789.  
  1790.   /* put all extent replicas on a free_list */
  1791.   {
  1792.     struct dup_block *dblk;
  1793.     int lim = dup_block_index;
  1794.     int num_free = 0;
  1795.     int num_used = 0;
  1796.  
  1797.     dup_free_list = 0;
  1798.  
  1799.     for (dblk = dup_block; dblk; dblk = dblk->next)
  1800.       {
  1801.     register int i;
  1802.  
  1803.     for (i = 0; i < lim; i++)
  1804.       {
  1805.             DUP dup = &(dblk->dups[i]);
  1806.         if (!DUP_MARKED_P (dup))
  1807.           {
  1808.                 memset ((char *) dup, 0, sizeof (*dup));
  1809.         dup->extent = (Lisp_Object) dup_free_list;
  1810.         dup_free_list = dup;
  1811.         num_free++;
  1812.           }
  1813.         else
  1814.           {
  1815.         num_used++;
  1816.         UNMARK_DUP (dup);
  1817.           }
  1818.       }
  1819.     lim = DUP_BLOCK_SIZE;
  1820.       }
  1821.     total_dups = num_used;
  1822.     total_free_dups = num_free;
  1823.   }
  1824.  
  1825.   /* Put all unmarked symbols on free list */
  1826.   {
  1827.     register struct symbol_block *sblk;
  1828.     register int lim = symbol_block_index;
  1829.     register int num_free = 0, num_used = 0;
  1830.  
  1831.     symbol_free_list = 0;
  1832.   
  1833.     for (sblk = symbol_block; sblk; sblk = sblk->next)
  1834.       {
  1835.     register int i;
  1836.     for (i = 0; i < lim; i++)
  1837.       if (!XMARKBIT (sblk->symbols[i].plist))
  1838.         {
  1839.           XFASTINT (sblk->symbols[i].value) = (int) symbol_free_list;
  1840.           symbol_free_list = &sblk->symbols[i];
  1841.           num_free++;
  1842.         }
  1843.       else
  1844.         {
  1845.           num_used++;
  1846.           sblk->symbols[i].name
  1847.         = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name);
  1848.           XUNMARK (sblk->symbols[i].plist);
  1849.         }
  1850.     lim = SYMBOL_BLOCK_SIZE;
  1851.       }
  1852.     total_symbols = num_used;
  1853.     total_free_symbols = num_free;
  1854.   }
  1855.  
  1856. #ifndef standalone
  1857.   /* Put all unmarked markers on free list.
  1858.      Dechain each one first from the buffer it points into. */
  1859.   {
  1860.     register struct marker_block *mblk;
  1861.     struct Lisp_Marker *tem1;
  1862.     register int lim = marker_block_index;
  1863.     register int num_free = 0, num_used = 0;
  1864.  
  1865.     marker_free_list = 0;
  1866.   
  1867.     for (mblk = marker_block; mblk; mblk = mblk->next)
  1868.       {
  1869.     register int i;
  1870.     for (i = 0; i < lim; i++)
  1871.       if (!XMARKBIT (mblk->markers[i].chain))
  1872.         {
  1873.           Lisp_Object tem;
  1874.           tem1 = &mblk->markers[i];  /* tem1 avoids Sun compiler bug */
  1875.           XSET (tem, Lisp_Marker, tem1);
  1876.           unchain_marker (tem);
  1877.           XFASTINT (mblk->markers[i].chain) = (int) marker_free_list;
  1878.           marker_free_list = &mblk->markers[i];
  1879.           num_free++;
  1880.         }
  1881.       else
  1882.         {
  1883.           num_used++;
  1884.           XUNMARK (mblk->markers[i].chain);
  1885.         }
  1886.     lim = MARKER_BLOCK_SIZE;
  1887.       }
  1888.  
  1889.     total_markers = num_used;
  1890.     total_free_markers = num_free;
  1891.   }
  1892.  
  1893.   /* Free all unmarked buffers */
  1894.   {
  1895.     register struct buffer *buffer = all_buffers, *prev = 0, *next;
  1896.  
  1897.     while (buffer)
  1898.       if (!XMARKBIT (buffer->name))
  1899.     {
  1900.       if (prev)
  1901.         prev->next = buffer->next;
  1902.       else
  1903.         all_buffers = buffer->next;
  1904.       next = buffer->next;
  1905.       xfree (buffer);
  1906.       buffer = next;
  1907.     }
  1908.       else
  1909.     {
  1910.       XUNMARK (buffer->name);
  1911.       prev = buffer, buffer = buffer->next;
  1912.     }
  1913.   }
  1914.  
  1915. #endif /* standalone */
  1916.  
  1917.   /* Free all unmarked vectors */
  1918.   {
  1919.     register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next;
  1920.     total_vector_size = 0;
  1921.  
  1922.     while (vector)
  1923.       if (!(vector->size & ARRAY_MARK_FLAG))
  1924.     {
  1925.       if (prev)
  1926.         prev->next = vector->next;
  1927.       else
  1928.         all_vectors = vector->next;
  1929.       next = vector->next;
  1930.       xfree (vector);
  1931.       vector = next;
  1932.     }
  1933.       else
  1934.     {
  1935.       vector->size &= ~ARRAY_MARK_FLAG;
  1936.       total_vector_size += vector->size;
  1937.       prev = vector, vector = vector->next;
  1938.     }
  1939.   }
  1940.  
  1941.  
  1942.   /* Put all unmarked strings on free list, free'ing the string chars
  1943.      of large unmarked strings */
  1944.   {
  1945.     register struct string_block *sblk;
  1946.     register int lim = string_block_index;
  1947.     register int num_free = 0, num_used = 0, num_small_used = 0, num_bytes = 0;
  1948.  
  1949.     string_free_list = 0;
  1950.  
  1951.     for (sblk = string_block; sblk; sblk = sblk->next)
  1952.       {
  1953.     register int i;
  1954.  
  1955.     for (i = 0; i < lim; i++)
  1956.       {
  1957.             struct Lisp_String *string = &(sblk->strings[i]);
  1958.         if (!XMARKBIT (string->dup_list))
  1959.           {
  1960.                 if (BIG_STRING_SIZE (string->size))
  1961.                   xfree ((char *)CHARS_TO_STRING_CHAR (string->data));
  1962.                 memset ((char *) string, 0, sizeof (struct Lisp_String));
  1963.         string->dup_list = (Lisp_Object) string_free_list;
  1964.         string_free_list = string;
  1965.         num_free++;
  1966.           }
  1967.         else
  1968.           {
  1969.         num_used++;
  1970.         XUNMARK (string->dup_list);
  1971.                 if (!(BIG_STRING_SIZE (string->size)))
  1972.                   num_small_used++;
  1973.                 num_bytes += string->size;
  1974.           }
  1975.       }
  1976.     lim = STRING_BLOCK_SIZE;
  1977.       }
  1978.     total_strings = num_used;
  1979.     total_short_strings = num_small_used;
  1980.     total_free_strings = num_free;
  1981.     total_string_size = num_bytes;
  1982.   }
  1983.  
  1984.   free_unmarked_events ();
  1985. }
  1986.  
  1987.  
  1988. /* Compactify string chars, relocating the reference to each --
  1989.    free any empty string_chars_block we see. */
  1990. static void
  1991. compact_string_chars ()
  1992. {
  1993.   struct string_chars_block *to_sb = first_string_chars_block;
  1994.   int to_pos = 0;
  1995.   struct string_chars_block *from_sb;
  1996.  
  1997.   /* Scan each existing string block sequentially, string by string.  */
  1998.   for (from_sb = first_string_chars_block; from_sb; from_sb = from_sb->next)
  1999.     {
  2000.       int from_pos = 0;
  2001.       /* FROM_POS is the index of the next string in the block.  */
  2002.       while (from_pos < from_sb->pos)
  2003.         {
  2004.           struct string_chars *from_s_chars = 
  2005.             (struct string_chars *) &from_sb->chars[from_pos];
  2006.           struct string_chars *to_s_chars;
  2007.           struct Lisp_String *string = from_s_chars->string;
  2008.           int size = string->size;
  2009.           int fullsize = STRING_FULLSIZE (size);
  2010.  
  2011.           if (BIG_STRING_SIZE (size))
  2012.             abort();
  2013.  
  2014.           /* Just skip it if it isn't marked.  */
  2015.           if (!XMARKBIT (string->dup_list))
  2016.             {
  2017.               from_pos += fullsize;
  2018.               continue;
  2019.             }
  2020.  
  2021.           /* If it won't fit in what's left of TO_SB, close TO_SB out
  2022.              and go on to the next string_chars_block.  We know that TO_SB
  2023.              cannot advance past FROM_SB here since FROM_SB is large enough
  2024.              to currently contain this string. */
  2025.           if ((to_pos + fullsize) > STRING_CHARS_BLOCK_SIZE)
  2026.             {
  2027.               to_sb->pos = to_pos;
  2028.               to_sb = to_sb->next;
  2029.               to_pos = 0;
  2030.             }
  2031.              
  2032.           /* Compute new address of this string
  2033.              and update TO_POS for the space being used.  */
  2034.           to_s_chars = (struct string_chars *) &to_sb->chars[to_pos];
  2035.  
  2036.           /* Copy the string_chars to the new place.  */
  2037.           if (from_s_chars != to_s_chars)
  2038.             memcpy (to_s_chars, from_s_chars, fullsize);
  2039.  
  2040.           /* Relocate FROM_S_CHARS's reference */
  2041.           string->data = &(to_s_chars->chars[0]);
  2042.              
  2043.           from_pos += fullsize;
  2044.           to_pos += fullsize;
  2045.         }
  2046.     }
  2047.  
  2048.   /* Set current to the last string chars block still used and 
  2049.      free any that follow. */
  2050.   {
  2051.     struct string_chars_block *this = to_sb->next;
  2052.  
  2053.     current_string_chars_block = to_sb;
  2054.     current_string_chars_block->pos = to_pos;
  2055.     current_string_chars_block->next = 0;
  2056.  
  2057.     while (this)
  2058.       {
  2059.         struct string_chars_block *tmp = this->next;
  2060.         xfree (this);
  2061.         this = tmp;
  2062.       }
  2063.   }
  2064. }
  2065.  
  2066.  
  2067. DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
  2068.   "Reclaim storage for Lisp objects no longer needed.\n\
  2069. Returns info on amount of space in use:\n\
  2070.  ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\
  2071.   (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS\n\
  2072.   (USED-FLOATS . FREE-FLOATS) (USED-EVENTS . FREE-EVENTS))\n\
  2073. Garbage collection happens automatically if you cons more than\n\
  2074. `gc-cons-threshold' bytes of Lisp data since previous garbage collection.")
  2075.   ()
  2076. {
  2077.   register struct gcpro *tail;
  2078.   register struct specbinding *bind;
  2079.   struct catchtag *catch;
  2080.   struct handler *handler;
  2081.   register struct backtrace *backlist;
  2082.   register Lisp_Object tem;
  2083.   char *omessage = echo_area_glyphs;
  2084.   char stack_top_variable;
  2085.   extern char *stack_bottom;
  2086.   register int i;
  2087.   SCREEN_PTR s = selected_screen;
  2088.  
  2089.   if (gc_in_progress != 0)
  2090.     return Qnil;
  2091.  
  2092.   if (gc_currently_forbidden)
  2093.     return Qnil;
  2094.  
  2095.   gc_in_progress = 1;
  2096.  
  2097. #if MAX_SAVE_STACK > 0
  2098.  
  2099.   /* Save a copy of the contents of the stack, for debugging.  */
  2100.   if (NILP (Vpurify_flag))
  2101.     {
  2102.       i = &stack_top_variable - stack_bottom;
  2103.       if (i < 0) i = -i;
  2104.       if (i < MAX_SAVE_STACK)
  2105.     {
  2106.       if (stack_copy == 0)
  2107.         stack_copy = (char *) xmalloc (stack_copy_size = i);
  2108.       else if (stack_copy_size < i)
  2109.         stack_copy = (char *) xrealloc (stack_copy, (stack_copy_size = i));
  2110.       if (stack_copy)
  2111.         {
  2112.           if ((int) (&stack_top_variable - stack_bottom) > 0)
  2113.         memcpy (stack_copy, stack_bottom, i);
  2114.           else
  2115.         memcpy (stack_copy, &stack_top_variable, i);
  2116.         }
  2117.     }
  2118.     }
  2119. #endif /* MAX_SAVE_STACK > 0 */
  2120.  
  2121.   if (!noninteractive)
  2122.     {
  2123. #ifdef HAVE_X_WINDOWS
  2124.       if (!x_show_gc_cursor (s))
  2125. #endif
  2126.     message ("Garbage collecting...");
  2127.     }
  2128.  
  2129.   /* Don't keep command history around forever
  2130.      You can't call nthcdr here because that's ^Gable, which will abort(),
  2131.      since gc_in_progress is true.
  2132.    */
  2133.   tem = Vcommand_history;
  2134.   for (i = 0; i < 30 && CONSP (tem); i++)
  2135.     tem = XCONS (tem)->cdr;
  2136.   if (CONSP (tem))
  2137.     XCONS (tem)->cdr = Qnil;
  2138.   /* Likewise for undo information.  */
  2139.   {
  2140.     register struct buffer *nextb = all_buffers;
  2141.  
  2142.     while (nextb)
  2143.       {
  2144.     nextb->undo_list 
  2145.       = truncate_undo_list (nextb->undo_list, undo_threshold,
  2146.                 undo_high_threshold);
  2147.     nextb = nextb->next;
  2148.       }
  2149.   }
  2150.  
  2151.   prepare_to_gc_events ();    /* cut some stuff loose */
  2152.   mark_command_event_queue ();
  2153.  
  2154.   /* Mark all the special slots that serve as the roots of accessibility.
  2155.  
  2156.      Usually the special slots to mark are contained in particular structures.
  2157.      Then we know no slot is marked twice because the structures don't overlap.
  2158.      In some cases, the structures point to the slots to be marked.
  2159.      For these, we use MARKBIT to avoid double marking of the slot.  */
  2160.  
  2161.   for (i = 0; i < staticidx; i++)
  2162.     mark_object (staticvec[i]);
  2163.   for (tail = gcprolist; tail; tail = tail->next)
  2164.     for (i = 0; i < tail->nvars; i++)
  2165.       if (!XMARKBIT (tail->var[i]))
  2166.     {
  2167.       mark_object (&tail->var[i]);
  2168.       XMARK (tail->var[i]);
  2169.     }
  2170.   for (bind = specpdl; bind != specpdl_ptr; bind++)
  2171.     {
  2172.       mark_object (&bind->symbol);
  2173.       mark_object (&bind->old_value);
  2174.     }
  2175.   for (catch = catchlist; catch; catch = catch->next)
  2176.     {
  2177.       mark_object (&catch->tag);
  2178.       mark_object (&catch->val);
  2179.     }  
  2180.   for (handler = handlerlist; handler; handler = handler->next)
  2181.     {
  2182.       mark_object (&handler->handlers);
  2183.       mark_object (&handler->handler_arg);
  2184.     }  
  2185.   for (backlist = backtrace_list; backlist; backlist = backlist->next)
  2186.     {
  2187.       if (!XMARKBIT (*backlist->function))
  2188.     {
  2189.       mark_object (backlist->function);
  2190.       XMARK (*backlist->function);
  2191.     }
  2192.       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
  2193.     i = 0;
  2194.       else
  2195.     i = backlist->nargs - 1;
  2196.       for (; i >= 0; i--)
  2197.     if (!XMARKBIT (backlist->args[i]))
  2198.       {
  2199.         mark_object (&backlist->args[i]);
  2200.         XMARK (backlist->args[i]);
  2201.       }
  2202.     }
  2203.  
  2204.   gc_sweep ();
  2205.  
  2206.   /* Clear the mark bits that we set in certain root slots.  */
  2207.  
  2208.   for (tail = gcprolist; tail; tail = tail->next)
  2209.     for (i = 0; i < tail->nvars; i++)
  2210.       XUNMARK (tail->var[i]);
  2211.   for (backlist = backtrace_list; backlist; backlist = backlist->next)
  2212.     {
  2213.       XUNMARK (*backlist->function);
  2214.       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
  2215.     i = 0;
  2216.       else
  2217.     i = backlist->nargs - 1;
  2218.       for (; i >= 0; i--)
  2219.     XUNMARK (backlist->args[i]);
  2220.     }  
  2221.   XUNMARK (buffer_defaults.name);
  2222.   XUNMARK (buffer_local_symbols.name);
  2223.  
  2224. /*  clear_marks (); */
  2225.  
  2226.   consing_since_gc = 0;
  2227.   if (gc_cons_threshold < 10000)
  2228.     gc_cons_threshold = 10000;
  2229.  
  2230.   if (!noninteractive)
  2231.     {
  2232. #ifdef HAVE_X_WINDOWS
  2233.       if (!x_show_normal_cursor (s))
  2234. #endif
  2235.     {
  2236.       if (omessage)
  2237.         message ("%s", omessage);
  2238.       else 
  2239.         message ("Garbage collecting...done");
  2240.     }
  2241.     }
  2242.   
  2243.   gc_in_progress = 0;
  2244.  
  2245.   {
  2246.     Lisp_Object ret [7];
  2247.     ret [0] = Fcons (make_number (total_conses),
  2248.              make_number (total_free_conses));
  2249.     ret [1] = Fcons (make_number (total_symbols),
  2250.              make_number (total_free_symbols));
  2251.     ret [2] = Fcons (make_number (total_markers),
  2252.              make_number (total_free_markers));
  2253.     ret [3] = make_number (total_string_size);
  2254.     ret [4] = make_number (total_vector_size);
  2255. #ifdef LISP_FLOAT_TYPE
  2256.     ret [5] = Fcons (make_number (total_floats),
  2257.              make_number (total_free_floats));
  2258. #else
  2259.     ret [5] = Fcons (make_number (0), make_number (0));
  2260. #endif
  2261.     ret [6] = Fcons (make_number (total_events),
  2262.              make_number (total_free_events));
  2263.     return Flist (7, ret);
  2264.   }
  2265. }
  2266.  
  2267. /* Initialization */
  2268.  
  2269. void
  2270. init_alloc_once ()
  2271. {
  2272. #ifdef PURESTAT
  2273.   memset (purestat, 0, sizeof (purestat));
  2274.   copying_function_object = 0;
  2275. #endif
  2276.  
  2277.   /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet!  */
  2278.   pureptr = 0;
  2279.   all_vectors = 0;
  2280.   ignore_warnings = 1;
  2281.   init_strings ();
  2282.   init_cons ();
  2283.   init_symbol ();
  2284.   init_marker ();
  2285. #ifdef LISP_FLOAT_TYPE
  2286.   init_float ();
  2287. #endif /* LISP_FLOAT_TYPE */
  2288.   init_extents ();
  2289.   ignore_warnings = 0;
  2290.   gcprolist = 0;
  2291.   staticidx = 0;
  2292.   consing_since_gc = 0;
  2293.   gc_cons_threshold = 100000;
  2294. #ifdef VIRT_ADDR_VARIES
  2295.   malloc_sbrk_unused = 1<<22;    /* A large number */
  2296.   malloc_sbrk_used = 100000;    /* as reasonable as any number */
  2297. #endif /* VIRT_ADDR_VARIES */
  2298. }
  2299.  
  2300. void
  2301. init_alloc ()
  2302. {
  2303.   gcprolist = 0;
  2304. }
  2305.  
  2306. void
  2307. syms_of_alloc ()
  2308. {
  2309.   DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold,
  2310.     "*Number of bytes of consing between garbage collections.\n\
  2311. Garbage collection can happen automatically once this many bytes have been\n\
  2312. allocated since the last garbage collection.  All data types count.\n\n\
  2313. Garbage collection happens automatically when `eval' or `funcall' are\n\
  2314. called.  (Note that `funcall' is called implicitly.)\n\
  2315. By binding this temporarily to a large number, you can effectively\n\
  2316. prevent garbage collection during a part of the program.");
  2317.  
  2318.   DEFVAR_INT ("pure-bytes-used", &pureptr,
  2319.     "Number of bytes of sharable Lisp data allocated so far.");
  2320.  
  2321. #if 0
  2322.   DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used,
  2323.     "Number of bytes of unshared memory allocated in this session.");
  2324.  
  2325.   DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused,
  2326.     "Number of bytes of unshared memory remaining available in this session.");
  2327. #endif
  2328.  
  2329.   DEFVAR_LISP ("purify-flag", &Vpurify_flag,
  2330.     "Non-nil means loading Lisp code in order to dump an executable.\n\
  2331. This means that certain objects should be allocated in shared (pure) space.");
  2332.  
  2333.   DEFVAR_INT ("undo-threshold", &undo_threshold,
  2334.     "Keep no more undo information once it exceeds this size.\n\
  2335. This threshold is applied when garbage collection happens.\n\
  2336. The size is counted as the number of bytes occupied,\n\
  2337. which includes both saved text and other data.");
  2338.   undo_threshold = 20000;
  2339.  
  2340.   DEFVAR_INT ("undo-high-threshold", &undo_high_threshold,
  2341.     "Don't keep more than this much size of undo information.\n\
  2342. A command which pushes past this size is itself forgotten.\n\
  2343. This threshold is applied when garbage collection happens.\n\
  2344. The size is counted as the number of bytes occupied,\n\
  2345. which includes both saved text and other data.");
  2346.   undo_high_threshold = 30000;
  2347.  
  2348.   DEFVAR_BOOL ("   gc-currently-forbidden", &gc_currently_forbidden,
  2349.                "internal variable used to control undo");
  2350.   gc_currently_forbidden = 0;
  2351.   Qgc_currently_forbidden = intern ("   gc-currently-forbidden");
  2352.  
  2353.   defsubr (&Scons);
  2354.   defsubr (&Slist);
  2355.   defsubr (&Svector);
  2356.   defsubr (&Smake_byte_code);
  2357.   defsubr (&Smake_list);
  2358.   defsubr (&Smake_vector);
  2359.   defsubr (&Smake_string);
  2360.   defsubr (&Smake_symbol);
  2361.   defsubr (&Smake_marker);
  2362.   defsubr (&Spurecopy);
  2363.   defsubr (&Sgarbage_collect);
  2364. }
  2365.