Annotation of GNUtools/emacs/src/alloc.c, revision 1.1.1.1

1.1       root        1: /* Storage allocation and gc for GNU Emacs Lisp interpreter.
                      2:    Copyright (C) 1985, 1986 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 1, 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 "window.h"
                     26: #endif
                     27: 
                     28: #define max(A,B) ((A) > (B) ? (A) : (B))
                     29: 
                     30: /* Macro to verify that storage intended for Lisp objects is not
                     31:    out of range to fit in the space for a pointer.
                     32:    ADDRESS is the start of the block, and SIZE
                     33:    is the amount of space within which objects can start.  */
                     34: #define VALIDATE_LISP_STORAGE(address, size)                   \
                     35: do                                                             \
                     36:   {                                                            \
                     37:     Lisp_Object val;                                           \
                     38:     XSET (val, Lisp_Cons, (char *) address + size);            \
                     39:     if ((char *) XCONS (val) != (char *) address + size)       \
                     40:       {                                                                \
                     41:        free (address);                                         \
                     42:        memory_full ();                                         \
                     43:       }                                                                \
                     44:   } while (0)
                     45: 
                     46: /* Number of bytes of consing done since the last gc */
                     47: int consing_since_gc;
                     48: 
                     49: /* Number of bytes of consing since gc before another gc should be done. */
                     50: int gc_cons_threshold;
                     51: 
                     52: /* value of consing_since_gc when undos were last truncated.  */
                     53: int consing_at_last_truncate;
                     54: 
                     55: /* Nonzero during gc */
                     56: int gc_in_progress;
                     57: 
                     58: #ifndef VIRT_ADDR_VARIES
                     59: extern
                     60: #endif /* VIRT_ADDR_VARIES */
                     61:  int malloc_sbrk_used;
                     62: 
                     63: #ifndef VIRT_ADDR_VARIES
                     64: extern
                     65: #endif /* VIRT_ADDR_VARIES */
                     66:  int malloc_sbrk_unused;
                     67: 
                     68: /* Two thresholds controlling how much undo information to keep.  */
                     69: int undo_threshold;
                     70: int undo_high_threshold;
                     71: 
                     72: /* Non-nil means defun should do purecopy on the function definition */
                     73: Lisp_Object Vpurify_flag;
                     74: 
                     75: /* Argument we give to Fsignal when memory is full.
                     76:    Preallocated since perhaps we can't allocate it when memory is full.  */
                     77: Lisp_Object memory_exhausted_message;
                     78: 
                     79: #ifndef HAVE_SHM
                     80: #ifdef VMS
                     81: int pure[PURESIZE / sizeof (int)];     /*no need to initialize - wasted space*/
                     82: #else
                     83: int pure[PURESIZE / sizeof (int)] = {0,};   /* Force it into data space! */
                     84: #endif /* NOT VMS */
                     85: #define PUREBEG (char *) pure
                     86: #else
                     87: #define pure PURE_SEG_BITS   /* Use shared memory segment */
                     88: #define PUREBEG (char *)PURE_SEG_BITS
                     89: #endif /* not HAVE_SHM */
                     90: 
                     91: /* Index in pure at which next pure object will be allocated. */
                     92: int pureptr;
                     93: 
                     94: /* If nonzero, this is a warning delivered by malloc and not yet displayed.  */
                     95: char *pending_malloc_warning;
                     96: 
                     97: Lisp_Object
                     98: malloc_warning_1 (str)
                     99:      Lisp_Object str;
                    100: {
                    101:   Fprinc (str, Vstandard_output);
                    102:   write_string ("\nKilling some buffers may delay running out of memory.\n", -1);
                    103:   write_string ("However, certainly by the time you receive the 95% warning,\n", -1);
                    104:   write_string ("you should clean up, kill this Emacs, and start a new one.", -1);
                    105:   return Qnil;
                    106: }
                    107: 
                    108: /* malloc calls this if it finds we are near exhausting storage */
                    109: malloc_warning (str)
                    110:      char *str;
                    111: {
                    112:   pending_malloc_warning = str;
                    113: }
                    114: 
                    115: display_malloc_warning ()
                    116: {
                    117:   register Lisp_Object val;
                    118: 
                    119:   val = build_string (pending_malloc_warning);
                    120:   pending_malloc_warning = 0;
                    121:   internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val);
                    122: }
                    123: 
                    124: /* Called if malloc returns zero */
                    125: memory_full ()
                    126: {
                    127:   while (1)
                    128:     Fsignal (Qerror, memory_exhausted_message);
                    129: }
                    130: 
                    131: /* like malloc and realloc but check for no memory left */
                    132: 
                    133: long *
                    134: xmalloc (size)
                    135:      int size;
                    136: {
                    137:   register long *val;
                    138:   /* Avoid failure if malloc (0) returns 0.  */
                    139:   if (size == 0)
                    140:     size = 1;
                    141:   val = (long *) malloc (size);
                    142:   if (!val) memory_full ();
                    143:   return val;
                    144: }
                    145: 
                    146: long *
                    147: xrealloc (block, size)
                    148:      long *block;
                    149:      int size;
                    150: {
                    151:   register long *val;
                    152:   /* Avoid failure if malloc (0) returns 0.  */
                    153:   if (size == 0)
                    154:     size = 1;
                    155:   val = (long *) realloc (block, size);
                    156:   if (!val) memory_full ();
                    157:   return val;
                    158: }
                    159: 
                    160: /* Allocation of cons cells */
                    161: /* We store cons cells inside of cons_blocks, allocating a new
                    162:  cons_block with malloc whenever necessary.  Cons cells reclaimed by
                    163:  GC are put on a free list to be reallocated before allocating
                    164:  any new cons cells from the latest cons_block.
                    165: 
                    166:  Each cons_block is just under 1016 bytes long,
                    167:  since malloc really allocates in units of powers of two
                    168:  and uses 8 bytes for its own overhead. */
                    169: 
                    170: #define CONS_BLOCK_SIZE \
                    171:   ((1016 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons))
                    172: 
                    173: struct cons_block
                    174:   {
                    175:     struct cons_block *next;
                    176:     struct Lisp_Cons conses[CONS_BLOCK_SIZE];
                    177:   };
                    178: 
                    179: struct cons_block *cons_block;
                    180: int cons_block_index;
                    181: 
                    182: struct Lisp_Cons *cons_free_list;
                    183: 
                    184: void
                    185: init_cons ()
                    186: {
                    187:   cons_block = (struct cons_block *) malloc (sizeof (struct cons_block));
                    188:   cons_block->next = 0;
                    189:   bzero (cons_block->conses, sizeof cons_block->conses);
                    190:   cons_block_index = 0;
                    191:   cons_free_list = 0;
                    192: }
                    193: 
                    194: /* Explicitly free a cons cell.  */
                    195: free_cons (ptr)
                    196:      struct Lisp_Cons *ptr;
                    197: {
                    198:   XFASTINT (ptr->car) = (int) cons_free_list;
                    199:   cons_free_list = ptr;
                    200: }
                    201: 
                    202: DEFUN ("cons", Fcons, Scons, 2, 2, 0,
                    203:   "Create a new cons, give it CAR and CDR as components, and return it.")
                    204:   (car, cdr)
                    205:      Lisp_Object car, cdr;
                    206: {
                    207:   register Lisp_Object val;
                    208: 
                    209:   if (cons_free_list)
                    210:     {
                    211:       XSET (val, Lisp_Cons, cons_free_list);
                    212:       cons_free_list = (struct Lisp_Cons *) XFASTINT (cons_free_list->car);
                    213:     }
                    214:   else
                    215:     {
                    216:       if (cons_block_index == CONS_BLOCK_SIZE)
                    217:        {
                    218:          register struct cons_block *new = (struct cons_block *) malloc (sizeof (struct cons_block));
                    219:          if (!new) memory_full ();
                    220:          VALIDATE_LISP_STORAGE (new, sizeof *new);
                    221:          new->next = cons_block;
                    222:          cons_block = new;
                    223:          cons_block_index = 0;
                    224:          XSET (val, Lisp_Cons, &cons_block->conses[CONS_BLOCK_SIZE - 1]);
                    225:        }
                    226:       XSET (val, Lisp_Cons, &cons_block->conses[cons_block_index++]);
                    227:     }
                    228:   XCONS (val)->car = car;
                    229:   XCONS (val)->cdr = cdr;
                    230:   consing_since_gc += sizeof (struct Lisp_Cons);
                    231:   return val;
                    232: }
                    233: 
                    234: DEFUN ("list", Flist, Slist, 0, MANY, 0,
                    235:   "Return a newly created list whose elements are the arguments (any number).")
                    236:   (nargs, args)
                    237:      int nargs;
                    238:      register Lisp_Object *args;
                    239: {
                    240:   register Lisp_Object len, val, val_tail;
                    241: 
                    242:   XFASTINT (len) = nargs;
                    243:   val = Fmake_list (len, Qnil);
                    244:   val_tail = val;
                    245:   while (!NULL (val_tail))
                    246:     {
                    247:       XCONS (val_tail)->car = *args++;
                    248:       val_tail = XCONS (val_tail)->cdr;
                    249:     }
                    250:   return val;
                    251: }
                    252: 
                    253: DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
                    254:   "Return a newly created list of length LENGTH, with each element being INIT.")
                    255:   (length, init)
                    256:      register Lisp_Object length, init;
                    257: {
                    258:   register Lisp_Object val;
                    259:   register int size;
                    260: 
                    261:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    262:     length = wrong_type_argument (Qnatnump, length);
                    263:   size = XINT (length);
                    264: 
                    265:   val = Qnil;
                    266:   while (size-- > 0)
                    267:     val = Fcons (init, val);
                    268:   return val;
                    269: }
                    270: 
                    271: /* Allocation of vectors */
                    272: 
                    273: struct Lisp_Vector *all_vectors;
                    274: 
                    275: DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
                    276:   "Return a newly created vector of length LENGTH, with each element being INIT.")
                    277:   (length, init)
                    278:      register Lisp_Object length, init;
                    279: {
                    280:   register int sizei, index;
                    281:   register Lisp_Object vector;
                    282:   register struct Lisp_Vector *p;
                    283: 
                    284:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    285:     length = wrong_type_argument (Qnatnump, length);
                    286:   sizei = XINT (length);
                    287: 
                    288:   p = (struct Lisp_Vector *) malloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object));
                    289:   if (p == 0)
                    290:     memory_full ();
                    291:   VALIDATE_LISP_STORAGE (p, 0);
                    292: 
                    293:   XSET (vector, Lisp_Vector, p);
                    294:   consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object);
                    295: 
                    296:   p->size = sizei;
                    297:   p->next = all_vectors;
                    298:   all_vectors = p;
                    299: 
                    300:   for (index = 0; index < sizei; index++)
                    301:     p->contents[index] = init;
                    302: 
                    303:   return vector;
                    304: }
                    305: 
                    306: DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
                    307:   "Return a newly created vector with our arguments (any number) as its elements.")
                    308:   (nargs, args)
                    309:      register int nargs;
                    310:      Lisp_Object *args;
                    311: {
                    312:   register Lisp_Object len, val;
                    313:   register int index;
                    314:   register struct Lisp_Vector *p;
                    315: 
                    316:   XFASTINT (len) = nargs;
                    317:   val = Fmake_vector (len, Qnil);
                    318:   p = XVECTOR (val);
                    319:   for (index = 0; index < nargs; index++)
                    320:     p->contents[index] = args[index];
                    321:   return val;
                    322: }
                    323: 
                    324: /* Allocation of symbols.
                    325:  Just like allocation of conses!
                    326: 
                    327:  Each symbol_block is just under 1016 bytes long,
                    328:  since malloc really allocates in units of powers of two
                    329:  and uses 8 bytes for its own overhead. */
                    330: 
                    331: #define SYMBOL_BLOCK_SIZE \
                    332:   ((1016 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
                    333: 
                    334: struct symbol_block
                    335:   {
                    336:     struct symbol_block *next;
                    337:     struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
                    338:   };
                    339: 
                    340: struct symbol_block *symbol_block;
                    341: int symbol_block_index;
                    342: 
                    343: struct Lisp_Symbol *symbol_free_list;
                    344: 
                    345: void
                    346: init_symbol ()
                    347: {
                    348:   symbol_block = (struct symbol_block *) malloc (sizeof (struct symbol_block));
                    349:   symbol_block->next = 0;
                    350:   bzero (symbol_block->symbols, sizeof symbol_block->symbols);
                    351:   symbol_block_index = 0;
                    352:   symbol_free_list = 0;
                    353: }
                    354: 
                    355: DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
                    356:   "Return a newly allocated uninterned symbol whose name is NAME.\n\
                    357: Its value and function definition are void, and its property list is NIL.")
                    358:   (str)
                    359:      Lisp_Object str;
                    360: {
                    361:   register Lisp_Object val;
                    362:   register struct Lisp_Symbol *p;
                    363: 
                    364:   CHECK_STRING (str, 0);
                    365: 
                    366:   if (symbol_free_list)
                    367:     {
                    368:       XSET (val, Lisp_Symbol, symbol_free_list);
                    369:       symbol_free_list
                    370:        = (struct Lisp_Symbol *) XFASTINT (symbol_free_list->value);
                    371:     }
                    372:   else
                    373:     {
                    374:       if (symbol_block_index == SYMBOL_BLOCK_SIZE)
                    375:        {
                    376:          struct symbol_block *new = (struct symbol_block *) malloc (sizeof (struct symbol_block));
                    377:          if (!new) memory_full ();
                    378:          VALIDATE_LISP_STORAGE (new, sizeof *new);
                    379:          new->next = symbol_block;
                    380:          symbol_block = new;
                    381:          symbol_block_index = 0;
                    382:        }
                    383:       XSET (val, Lisp_Symbol, &symbol_block->symbols[symbol_block_index++]);
                    384:     }
                    385:   p = XSYMBOL (val);
                    386:   p->name = XSTRING (str);
                    387:   p->plist = Qnil;
                    388:   p->value = Qunbound;
                    389:   p->function = Qunbound;
                    390:   p->next = 0;
                    391:   consing_since_gc += sizeof (struct Lisp_Symbol);
                    392:   return val;
                    393: }
                    394: 
                    395: /* Allocation of markers.
                    396:  Works like allocation of conses. */
                    397: 
                    398: #define MARKER_BLOCK_SIZE \
                    399:   ((1016 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker))
                    400: 
                    401: struct marker_block
                    402:   {
                    403:     struct marker_block *next;
                    404:     struct Lisp_Marker markers[MARKER_BLOCK_SIZE];
                    405:   };
                    406: 
                    407: struct marker_block *marker_block;
                    408: int marker_block_index;
                    409: 
                    410: struct Lisp_Marker *marker_free_list;
                    411: 
                    412: void
                    413: init_marker ()
                    414: {
                    415:   marker_block = (struct marker_block *) malloc (sizeof (struct marker_block));
                    416:   marker_block->next = 0;
                    417:   bzero (marker_block->markers, sizeof marker_block->markers);
                    418:   marker_block_index = 0;
                    419:   marker_free_list = 0;
                    420: }
                    421: 
                    422: DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
                    423:   "Return a newly allocated marker which does not point at any place.")
                    424:   ()
                    425: {
                    426:   register Lisp_Object val;
                    427:   register struct Lisp_Marker *p;
                    428: 
                    429:   if (marker_free_list)
                    430:     {
                    431:       XSET (val, Lisp_Marker, marker_free_list);
                    432:       marker_free_list
                    433:        = (struct Lisp_Marker *) XFASTINT (marker_free_list->chain);
                    434:     }
                    435:   else
                    436:     {
                    437:       if (marker_block_index == MARKER_BLOCK_SIZE)
                    438:        {
                    439:          struct marker_block *new = (struct marker_block *) malloc (sizeof (struct marker_block));
                    440:          if (!new) memory_full ();
                    441:          VALIDATE_LISP_STORAGE (new, sizeof *new);
                    442:          new->next = marker_block;
                    443:          marker_block = new;
                    444:          marker_block_index = 0;
                    445:        }
                    446:       XSET (val, Lisp_Marker, &marker_block->markers[marker_block_index++]);
                    447:     }
                    448:   p = XMARKER (val);
                    449:   p->buffer = 0;
                    450:   p->bufpos = 0;
                    451:   p->chain = Qnil;
                    452:   consing_since_gc += sizeof (struct Lisp_Marker);
                    453:   return val;
                    454: }
                    455: 
                    456: /* Allocation of strings */
                    457: 
                    458: /* Strings reside inside of string_blocks.  The entire data of the string,
                    459:  both the size and the contents, live in part of the `chars' component of a string_block.
                    460:  The `pos' component is the index within `chars' of the first free byte.
                    461: 
                    462:  first_string_block points to the first string_block ever allocated.
                    463:  Each block points to the next one with its `next' field.
                    464:  The `prev' fields chain in reverse order.
                    465:  The last one allocated is the one currently being filled.
                    466:  current_string_block points to it.
                    467: 
                    468:  The string_blocks that hold individual large strings
                    469:  go in a separate chain, started by large_string_blocks.  */
                    470: 
                    471: 
                    472: /* String blocks contain this many useful bytes.
                    473:    8184 is power of 2, minus 8 for malloc overhead. */
                    474: #define STRING_BLOCK_SIZE (8184 - sizeof (struct string_block_head))
                    475: 
                    476: /* A string bigger than this gets its own specially-made string block
                    477:  if it doesn't fit in the current one. */
                    478: #define STRING_BLOCK_OUTSIZE 1024
                    479: 
                    480: struct string_block_head
                    481:   {
                    482:     struct string_block *next, *prev;
                    483:     int pos;
                    484:   };
                    485: 
                    486: struct string_block
                    487:   {
                    488:     struct string_block *next, *prev;
                    489:     int pos;
                    490:     char chars[STRING_BLOCK_SIZE];
                    491:   };
                    492: 
                    493: /* This points to the string block we are now allocating strings.  */
                    494: 
                    495: struct string_block *current_string_block;
                    496: 
                    497: /* This points to the oldest string block, the one that starts the chain.  */
                    498: 
                    499: struct string_block *first_string_block;
                    500: 
                    501: /* Last string block in chain of those made for individual large strings.  */
                    502: 
                    503: struct string_block *large_string_blocks;
                    504: 
                    505: /* If SIZE is the length of a string, this returns how many bytes
                    506:    the string occupies in a string_block (including padding).  */
                    507: 
                    508: #define STRING_FULLSIZE(SIZE)   \
                    509: (((SIZE) + 2 * sizeof (int)) & ~(sizeof (int) - 1))
                    510: 
                    511: void
                    512: init_strings ()
                    513: {
                    514:   current_string_block = (struct string_block *) malloc (sizeof (struct string_block));
                    515:   first_string_block = current_string_block;
                    516:   consing_since_gc += sizeof (struct string_block);
                    517:   current_string_block->next = 0;
                    518:   current_string_block->prev = 0;
                    519:   current_string_block->pos = 0;
                    520:   large_string_blocks = 0;
                    521: }
                    522: 
                    523: static Lisp_Object make_uninit_string ();
                    524: 
                    525: DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0,
                    526:   "Return a newly created string of length LENGTH, with each element being INIT.\n\
                    527: Both LENGTH and INIT must be numbers.")
                    528:   (length, init)
                    529:      Lisp_Object length, init;
                    530: {
                    531:   register Lisp_Object val;
                    532:   register unsigned char *p, *end, c;
                    533: 
                    534:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    535:     length = wrong_type_argument (Qnatnump, length);
                    536:   CHECK_NUMBER (init, 1);
                    537:   val = make_uninit_string (XINT (length));
                    538:   c = XINT (init);
                    539:   p = XSTRING (val)->data;
                    540:   end = p + XSTRING (val)->size;
                    541:   while (p != end)
                    542:     *p++ = c;
                    543:   *p = 0;
                    544:   return val;
                    545: }
                    546: 
                    547: Lisp_Object
                    548: make_string (contents, length)
                    549:      char *contents;
                    550:      int length;
                    551: {
                    552:   register Lisp_Object val;
                    553:   val = make_uninit_string (length, 0);
                    554:   bcopy (contents, XSTRING (val)->data, length);
                    555:   return val;
                    556: }
                    557: 
                    558: Lisp_Object
                    559: build_string (str)
                    560:      char *str;
                    561: {
                    562:   return make_string (str, strlen (str));
                    563: }
                    564: 
                    565: static Lisp_Object
                    566: make_uninit_string (length)
                    567:      int length;
                    568: {
                    569:   register Lisp_Object val;
                    570:   register int fullsize = STRING_FULLSIZE (length);
                    571: 
                    572:   if (length < 0) abort ();
                    573: 
                    574:   if (fullsize <= STRING_BLOCK_SIZE - current_string_block->pos)
                    575:     /* This string can fit in the current string block */
                    576:     {
                    577:       XSET (val, Lisp_String,
                    578:            (struct Lisp_String *) (current_string_block->chars + current_string_block->pos));
                    579:       current_string_block->pos += fullsize;
                    580:     }
                    581:   else if (fullsize > STRING_BLOCK_OUTSIZE)
                    582:     /* This string gets its own string block */
                    583:     {
                    584:       register struct string_block *new
                    585:        = (struct string_block *) malloc (sizeof (struct string_block_head) + fullsize);
                    586:       if (!new) memory_full ();
                    587:       VALIDATE_LISP_STORAGE (new, 0);
                    588:       consing_since_gc += sizeof (struct string_block_head) + fullsize;
                    589:       new->pos = fullsize;
                    590:       new->next = large_string_blocks;
                    591:       large_string_blocks = new;
                    592:       XSET (val, Lisp_String,
                    593:            (struct Lisp_String *) ((struct string_block_head *)new + 1));
                    594:     }
                    595:   else
                    596:     /* Make a new current string block and start it off with this string */
                    597:     {
                    598:       register struct string_block *new
                    599:        = (struct string_block *) malloc (sizeof (struct string_block));
                    600:       if (!new) memory_full ();
                    601:       VALIDATE_LISP_STORAGE (new, sizeof *new);
                    602:       consing_since_gc += sizeof (struct string_block);
                    603:       current_string_block->next = new;
                    604:       new->prev = current_string_block;
                    605:       new->next = 0;
                    606:       current_string_block = new;
                    607:       new->pos = fullsize;
                    608:       XSET (val, Lisp_String,
                    609:            (struct Lisp_String *) current_string_block->chars);
                    610:     }
                    611:     
                    612:   XSTRING (val)->size = length;
                    613:   XSTRING (val)->data[length] = 0;
                    614: 
                    615:   return val;
                    616: }
                    617: 
                    618: /* Must get an error if pure storage is full,
                    619:  since if it cannot hold a large string
                    620:  it may be able to hold conses that point to that string;
                    621:  then the string is not protected from gc. */
                    622: 
                    623: Lisp_Object
                    624: make_pure_string (data, length)
                    625:      char *data;
                    626:      int length;
                    627: {
                    628:   register Lisp_Object new;
                    629:   register int size = sizeof (int) + length + 1;
                    630: 
                    631:   if (pureptr + size > PURESIZE)
                    632:     error ("Pure Lisp storage exhausted");
                    633:   XSET (new, Lisp_String, PUREBEG + pureptr);
                    634:   XSTRING (new)->size = length;
                    635:   bcopy (data, XSTRING (new)->data, length);
                    636:   XSTRING (new)->data[length] = 0;
                    637:   pureptr += (size + sizeof (int) - 1)
                    638:             / sizeof (int) * sizeof (int);
                    639:   return new;
                    640: }
                    641: 
                    642: Lisp_Object
                    643: pure_cons (car, cdr)
                    644:      Lisp_Object car, cdr;
                    645: {
                    646:   register Lisp_Object new;
                    647: 
                    648:   if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE)
                    649:     error ("Pure Lisp storage exhausted");
                    650:   XSET (new, Lisp_Cons, PUREBEG + pureptr);
                    651:   pureptr += sizeof (struct Lisp_Cons);
                    652:   XCONS (new)->car = Fpurecopy (car);
                    653:   XCONS (new)->cdr = Fpurecopy (cdr);
                    654:   return new;
                    655: }
                    656: 
                    657: Lisp_Object
                    658: make_pure_vector (len)
                    659:      int len;
                    660: {
                    661:   register Lisp_Object new;
                    662:   register int size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object);
                    663: 
                    664:   if (pureptr + size > PURESIZE)
                    665:     error ("Pure Lisp storage exhausted");
                    666: 
                    667:   XSET (new, Lisp_Vector, PUREBEG + pureptr);
                    668:   pureptr += size;
                    669:   XVECTOR (new)->size = len;
                    670:   return new;
                    671: }
                    672: 
                    673: DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
                    674:   "Make a copy of OBJECT in pure storage.\n\
                    675: Recursively copies contents of vectors and cons cells.\n\
                    676: Does not copy symbols.")
                    677:   (obj)
                    678:      register Lisp_Object obj;
                    679: {
                    680:   register Lisp_Object new, tem;
                    681:   register int i;
                    682: 
                    683:   if (NULL (Vpurify_flag))
                    684:     return obj;
                    685: 
                    686:   if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)
                    687:       && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure)
                    688:     return obj;
                    689: 
                    690: #ifdef SWITCH_ENUM_BUG
                    691:   switch ((int) XTYPE (obj))
                    692: #else
                    693:   switch (XTYPE (obj))
                    694: #endif
                    695:     {
                    696:     case Lisp_Marker:
                    697:       error ("Attempt to copy a marker to pure storage");
                    698: 
                    699:     case Lisp_Cons:
                    700:       return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr);
                    701: 
                    702:     case Lisp_String:
                    703:       return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size);
                    704: 
                    705:     case Lisp_Vector:
                    706:       new = make_pure_vector (XVECTOR (obj)->size);
                    707:       for (i = 0; i < XVECTOR (obj)->size; i++)
                    708:        {
                    709:          tem = XVECTOR (obj)->contents[i];
                    710:          XVECTOR (new)->contents[i] = Fpurecopy (tem);
                    711:        }
                    712:       return new;
                    713: 
                    714:     default:
                    715:       return obj;
                    716:     }
                    717: }
                    718: 
                    719: /* Recording what needs to be marked for gc.  */
                    720: 
                    721: struct gcpro *gcprolist;
                    722: 
                    723: #define NSTATICS 200
                    724: 
                    725: int staticidx = 0;
                    726: 
                    727: #ifdef __GNUC__
                    728: Lisp_Object *staticvec[NSTATICS] = {0};
                    729: #else
                    730: char staticvec1[NSTATICS * sizeof (Lisp_Object *)] = {0};
                    731: #define staticvec ((Lisp_Object **) staticvec1)
                    732: #endif
                    733: 
                    734: /* Put an entry in staticvec, pointing at the variable whose address is given */
                    735: 
                    736: void
                    737: staticpro (varaddress)
                    738:      Lisp_Object *varaddress;
                    739: {
                    740:   staticvec[staticidx++] = varaddress;
                    741:   if (staticidx >= NSTATICS)
                    742:     abort ();
                    743: }
                    744: 
                    745: struct catchtag
                    746:   {
                    747:     Lisp_Object tag;
                    748:     Lisp_Object val;
                    749:     struct catchtag *next;
                    750: /*    jmp_buf jmp;  /* We don't need this for GC purposes */
                    751:   };
                    752: 
                    753: extern struct catchtag *catchlist;
                    754: 
                    755: struct backtrace
                    756:   {
                    757:     struct backtrace *next;
                    758:     Lisp_Object *function;
                    759:     Lisp_Object *args; /* Points to vector of args. */
                    760:     int nargs;         /* length of vector */
                    761:               /* if nargs is UNEVALLED, args points to slot holding list of unevalled args */
                    762:     char evalargs;
                    763:   };
                    764: 
                    765: extern struct backtrace *backtrace_list;
                    766: 
                    767: /* Two flags that are set during GC in the `size' component
                    768:    of a string or vector.  On some machines, these flags
                    769:    are defined by the m- file to be different bits.  */
                    770: 
                    771: /* On vector, means it has been marked.
                    772:    On string size field or a reference to a string,
                    773:    means not the last reference in the chain.  */
                    774: 
                    775: #ifndef ARRAY_MARK_FLAG
                    776: #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
                    777: #endif /* no ARRAY_MARK_FLAG */
                    778: 
                    779: /* Any slot that is a Lisp_Object can point to a string
                    780:    and thus can be put on a string's reference-chain
                    781:    and thus may need to have its ARRAY_MARK_FLAG set.
                    782:    This includes the slots whose markbits are used to mark
                    783:    the containing objects.  */
                    784: 
                    785: #if ARRAY_MARK_FLAG == MARKBIT
                    786: you lose
                    787: #endif
                    788: 
                    789: int total_conses, total_markers, total_symbols, total_string_size, total_vector_size;
                    790: int total_free_conses, total_free_markers, total_free_symbols;
                    791: 
                    792: static void mark_object (), mark_buffer ();
                    793: static void clear_marks (), gc_sweep ();
                    794: static void compact_strings ();
                    795: 
                    796: DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
                    797:   "Reclaim storage for Lisp objects no longer needed.\n\
                    798: Returns info on amount of space in use:\n\
                    799:  ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\
                    800:   (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS)\n\
                    801: Garbage collection happens automatically if you cons more than\n\
                    802: gc-cons-threshold  bytes of Lisp data since previous garbage collection.")
                    803:   ()
                    804: {
                    805:   register struct gcpro *tail;
                    806:   register struct specbinding *bind;
                    807:   struct catchtag *catch;
                    808:   struct handler *handler;
                    809:   register struct backtrace *backlist;
                    810:   register Lisp_Object tem;
                    811:   char *omessage = echo_area_contents;
                    812: 
                    813:   register int i;
                    814: 
                    815:   if (!noninteractive)
                    816:     message1 ("Garbage collecting...");
                    817: 
                    818:   /* Don't keep command history around forever */
                    819:   tem = Fnthcdr (make_number (30), Vcommand_history);
                    820:   if (CONSP (tem))
                    821:     XCONS (tem)->cdr = Qnil;
                    822:   /* Likewise for undo information.  */
                    823:   truncate_all_undos ();
                    824: 
                    825:   gc_in_progress = 1;
                    826: 
                    827: /*  clear_marks ();  */
                    828: 
                    829:   /* In each "large string", set the MARKBIT of the size field.
                    830:      That enables mark_object to recognize them.  */
                    831:   {
                    832:     register struct string_block *b;
                    833:     for (b = large_string_blocks; b; b = b->next)
                    834:       ((struct Lisp_String *)(&b->chars[0]))->size |= MARKBIT;
                    835:   }
                    836: 
                    837:   /* Mark all the special slots that serve as the roots of accessibility.
                    838: 
                    839:      Usually the special slots to mark are contained in particular structures.
                    840:      Then we know no slot is marked twice because the structures don't overlap.
                    841:      In some cases, the structures point to the slots to be marked.
                    842:      For these, we use MARKBIT to avoid double marking of the slot.  */
                    843: 
                    844:   for (i = 0; i < staticidx; i++)
                    845:     mark_object (staticvec[i]);
                    846:   for (tail = gcprolist; tail; tail = tail->next)
                    847:     for (i = 0; i < tail->nvars; i++)
                    848:       if (!XMARKBIT (tail->var[i]))
                    849:        {
                    850:          mark_object (&tail->var[i]);
                    851:          XMARK (tail->var[i]);
                    852:        }
                    853:   for (bind = specpdl; bind != specpdl_ptr; bind++)
                    854:     {
                    855:       mark_object (&bind->symbol);
                    856:       mark_object (&bind->old_value);
                    857:     }
                    858:   for (catch = catchlist; catch; catch = catch->next)
                    859:     {
                    860:       mark_object (&catch->tag);
                    861:       mark_object (&catch->val);
                    862:     }  
                    863:   for (handler = handlerlist; handler; handler = handler->next)
                    864:     {
                    865:       mark_object (&handler->handler);
                    866:       mark_object (&handler->var);
                    867:     }  
                    868:   for (backlist = backtrace_list; backlist; backlist = backlist->next)
                    869:     {
                    870:       if (!XMARKBIT (*backlist->function))
                    871:        {
                    872:          mark_object (backlist->function);
                    873:          XMARK (*backlist->function);
                    874:        }
                    875:       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
                    876:        i = 0;
                    877:       else
                    878:        i = backlist->nargs - 1;
                    879:       for (; i >= 0; i--)
                    880:        if (!XMARKBIT (backlist->args[i]))
                    881:          {
                    882:            mark_object (&backlist->args[i]);
                    883:            XMARK (backlist->args[i]);
                    884:          }
                    885:     }  
                    886: 
                    887:   gc_sweep ();
                    888: 
                    889:   /* Clear the mark bits that we set in certain root slots.  */
                    890: 
                    891:   for (tail = gcprolist; tail; tail = tail->next)
                    892:     for (i = 0; i < tail->nvars; i++)
                    893:       XUNMARK (tail->var[i]);
                    894:   for (backlist = backtrace_list; backlist; backlist = backlist->next)
                    895:     {
                    896:       XUNMARK (*backlist->function);
                    897:       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
                    898:        i = 0;
                    899:       else
                    900:        i = backlist->nargs - 1;
                    901:       for (; i >= 0; i--)
                    902:        XUNMARK (backlist->args[i]);
                    903:     }  
                    904:   XUNMARK (buffer_defaults.name);
                    905:   XUNMARK (buffer_local_symbols.name);
                    906: 
                    907: /*  clear_marks (); */
                    908:   gc_in_progress = 0;
                    909: 
                    910:   consing_since_gc = 0;
                    911:   consing_at_last_truncate = 0;
                    912:   if (gc_cons_threshold < 10000)
                    913:     gc_cons_threshold = 10000;
                    914: 
                    915:   if (omessage)
                    916:     message1 (omessage);
                    917:   else if (!noninteractive)
                    918:     message1 ("Garbage collecting...done");
                    919: 
                    920:   return Fcons (Fcons (make_number (total_conses),
                    921:                       make_number (total_free_conses)),
                    922:                Fcons (Fcons (make_number (total_symbols),
                    923:                              make_number (total_free_symbols)),
                    924:                       Fcons (Fcons (make_number (total_markers),
                    925:                                     make_number (total_free_markers)),
                    926:                              Fcons (make_number (total_string_size),
                    927:                                     Fcons (make_number (total_vector_size),
                    928:                                            Qnil)))));
                    929: }
                    930: 
                    931: #if 0
                    932: static void
                    933: clear_marks ()
                    934: {
                    935:   /* Clear marks on all conses */
                    936:   {
                    937:     register struct cons_block *cblk;
                    938:     register int lim = cons_block_index;
                    939:   
                    940:     for (cblk = cons_block; cblk; cblk = cblk->next)
                    941:       {
                    942:        register int i;
                    943:        for (i = 0; i < lim; i++)
                    944:          XUNMARK (cblk->conses[i].car);
                    945:        lim = CONS_BLOCK_SIZE;
                    946:       }
                    947:   }
                    948:   /* Clear marks on all symbols */
                    949:   {
                    950:     register struct symbol_block *sblk;
                    951:     register int lim = symbol_block_index;
                    952:   
                    953:     for (sblk = symbol_block; sblk; sblk = sblk->next)
                    954:       {
                    955:        register int i;
                    956:        for (i = 0; i < lim; i++)
                    957:          {
                    958:            XUNMARK (sblk->symbols[i].plist);
                    959:          }
                    960:        lim = SYMBOL_BLOCK_SIZE;
                    961:       }
                    962:   }
                    963:   /* Clear marks on all markers */
                    964:   {
                    965:     register struct marker_block *sblk;
                    966:     register int lim = marker_block_index;
                    967:   
                    968:     for (sblk = marker_block; sblk; sblk = sblk->next)
                    969:       {
                    970:        register int i;
                    971:        for (i = 0; i < lim; i++)
                    972:          XUNMARK (sblk->markers[i].chain);
                    973:        lim = MARKER_BLOCK_SIZE;
                    974:       }
                    975:   }
                    976:   /* Clear mark bits on all buffers */
                    977:   {
                    978:     register struct buffer *nextb = all_buffers;
                    979: 
                    980:     while (nextb)
                    981:       {
                    982:        XUNMARK (nextb->name);
                    983:        nextb = nextb->next;
                    984:       }
                    985:   }
                    986: }
                    987: #endif
                    988: 
                    989: /* Mark reference to a Lisp_Object.  If the object referred to
                    990:    has not been seen yet, recursively mark all the references contained in it.
                    991: 
                    992:    If the object referenced is a short string, the referrencing slot
                    993:    is threaded into a chain of such slots, pointed to from
                    994:    the `size' field of the string.  The actual string size
                    995:    lives in the last slot in the chain.  We recognize the end
                    996:    because it is < (unsigned) STRING_BLOCK_SIZE.  */
                    997: 
                    998: static void
                    999: mark_object (objptr)
                   1000:      Lisp_Object *objptr;
                   1001: {
                   1002:   register Lisp_Object obj;
                   1003: 
                   1004:   obj = *objptr;
                   1005:   XUNMARK (obj);
                   1006: 
                   1007:  loop:
                   1008: 
                   1009:   if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)
                   1010:       && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure)
                   1011:     return;
                   1012: 
                   1013: #ifdef SWITCH_ENUM_BUG
                   1014:   switch ((int) XGCTYPE (obj))
                   1015: #else
                   1016:   switch (XGCTYPE (obj))
                   1017: #endif
                   1018:     {
                   1019:     case Lisp_String:
                   1020:       {
                   1021:        register struct Lisp_String *ptr = XSTRING (obj);
                   1022: 
                   1023:        if (ptr->size & MARKBIT)
                   1024:          /* A large string.  Just set ARRAY_MARK_FLAG.  */
                   1025:          ptr->size |= ARRAY_MARK_FLAG;
                   1026:        else
                   1027:          {
                   1028:            /* A small string.  Put this reference
                   1029:               into the chain of references to it.
                   1030:               The address OBJPTR is even, so if the address
                   1031:               includes MARKBIT, put it in the low bit
                   1032:               when we store OBJPTR into the size field.  */
                   1033: 
                   1034:            if (XMARKBIT (*objptr))
                   1035:              {
                   1036:                XFASTINT (*objptr) = ptr->size;
                   1037:                XMARK (*objptr);
                   1038:              }
                   1039:            else
                   1040:              XFASTINT (*objptr) = ptr->size;
                   1041:            if ((int)objptr & 1) abort ();
                   1042:            ptr->size = (int) objptr & ~MARKBIT;
                   1043:            if ((int) objptr & MARKBIT)
                   1044:              ptr->size ++;
                   1045:          }
                   1046:       }
                   1047:       break;
                   1048: 
                   1049:     case Lisp_Vector:
                   1050:     case Lisp_Window:
                   1051:     case Lisp_Process:
                   1052:     case Lisp_Window_Configuration:
                   1053:       {
                   1054:        register struct Lisp_Vector *ptr = XVECTOR (obj);
                   1055:        register int size = ptr->size;
                   1056:        register int i;
                   1057: 
                   1058:        if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
                   1059:        ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
                   1060:        for (i = 0; i < size; i++)     /* and then mark its elements */
                   1061:          mark_object (&ptr->contents[i]);
                   1062:       }
                   1063:       break;
                   1064: 
                   1065: #if 0
                   1066:     case Lisp_Temp_Vector:
                   1067:       {
                   1068:        register struct Lisp_Vector *ptr = XVECTOR (obj);
                   1069:        register int size = ptr->size;
                   1070:        register int i;
                   1071: 
                   1072:        for (i = 0; i < size; i++)     /* and then mark its elements */
                   1073:          mark_object (&ptr->contents[i]);
                   1074:       }
                   1075:       break;
                   1076: #endif 0
                   1077: 
                   1078:     case Lisp_Symbol:
                   1079:       {
                   1080:        register struct Lisp_Symbol *ptr = XSYMBOL (obj);
                   1081:        struct Lisp_Symbol *ptrx;
                   1082: 
                   1083:        if (XMARKBIT (ptr->plist)) break;
                   1084:        XMARK (ptr->plist);
                   1085:        XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
                   1086:        mark_object (&ptr->name);
                   1087:        mark_object ((Lisp_Object *) &ptr->value);
                   1088:        mark_object (&ptr->function);
                   1089:        mark_object (&ptr->plist);
                   1090:        ptr = ptr->next;
                   1091:        if (ptr)
                   1092:          {
                   1093:            ptrx = ptr;         /* Use pf ptrx avoids compiler bug on Sun */
                   1094:            XSETSYMBOL (obj, ptrx);
                   1095:            goto loop;
                   1096:          }
                   1097:       }
                   1098:       break;
                   1099: 
                   1100:     case Lisp_Marker:
                   1101:       XMARK (XMARKER (obj)->chain);
                   1102:       /* DO NOT mark thru the marker's chain.
                   1103:         The buffer's markers chain does not preserve markers from gc;
                   1104:         instead, markers are removed from the chain when they are freed by gc. */
                   1105:       break;
                   1106: 
                   1107:     case Lisp_Cons:
                   1108:     case Lisp_Buffer_Local_Value:
                   1109:     case Lisp_Some_Buffer_Local_Value:
                   1110:       {
                   1111:        register struct Lisp_Cons *ptr = XCONS (obj);
                   1112:        if (XMARKBIT (ptr->car)) break;
                   1113:        XMARK (ptr->car);
                   1114:        /* If the cdr is nil, avoid recursion for the car.  */
                   1115:        if (EQ (ptr->cdr, Qnil))
                   1116:          {
                   1117:            objptr = &ptr->car;
                   1118:            obj = ptr->car;
                   1119:            XUNMARK (obj);
                   1120:            goto loop;
                   1121:          }
                   1122:        /* If the cdr is (INTEGER . nil), mark the cdr first,
                   1123:           to avoid recursion for the car.  This case occurs
                   1124:           in every compiled function.  */
                   1125:        if (XTYPE (ptr->cdr) == Lisp_Cons
                   1126:            && XGCTYPE (XCONS (ptr->cdr)->car) == Lisp_Int
                   1127:            && EQ (XCONS (ptr->cdr)->cdr, Qnil))
                   1128:          {
                   1129:            mark_object (&ptr->cdr);
                   1130:            objptr = &ptr->car;
                   1131:            obj = ptr->car;
                   1132:            XUNMARK (obj);
                   1133:            goto loop;
                   1134:          }
                   1135:        mark_object (&ptr->car);
                   1136:        objptr = &ptr->cdr;
                   1137:        obj = ptr->cdr;
                   1138:        goto loop;
                   1139:       }
                   1140: 
                   1141:     case Lisp_Buffer:
                   1142:       if (!XMARKBIT (XBUFFER (obj)->name))
                   1143:        mark_buffer (obj);
                   1144:       break;
                   1145: 
                   1146:     case Lisp_Int:
                   1147:     case Lisp_Void:
                   1148:     case Lisp_Subr:
                   1149:     case Lisp_Intfwd:
                   1150:     case Lisp_Boolfwd:
                   1151:     case Lisp_Objfwd:
                   1152:     case Lisp_Buffer_Objfwd:
                   1153:     case Lisp_Internal_Stream:
                   1154:     /* Don't bother with Lisp_Buffer_Objfwd,
                   1155:        since all markable slots in current buffer marked anyway.  */
                   1156:     /* Don't need to do Lisp_Objfwd, since the places they point
                   1157:        are protected with staticpro.  */
                   1158:       break;
                   1159: 
                   1160:     default:
                   1161:       abort ();
                   1162:     }
                   1163: }
                   1164: 
                   1165: /* Mark the pointers in a buffer structure.  */
                   1166: 
                   1167: static void
                   1168: mark_buffer (buf)
                   1169:      Lisp_Object buf;
                   1170: {
                   1171:   Lisp_Object tem;
                   1172:   register struct buffer *buffer = XBUFFER (buf);
                   1173:   register Lisp_Object *ptr;
                   1174: 
                   1175:   /* This is the buffer's markbit */
                   1176:   mark_object (&buffer->name);
                   1177:   XMARK (buffer->name);
                   1178: 
                   1179:   for (ptr = &buffer->name + 1;
                   1180:        (char *)ptr < (char *)buffer + sizeof (struct buffer);
                   1181:        ptr++)
                   1182:     mark_object (ptr);
                   1183: }
                   1184: 
                   1185: /* Find all structures not marked, and free them. */
                   1186: 
                   1187: static void
                   1188: gc_sweep ()
                   1189: {
                   1190:   total_string_size = 0;
                   1191:   compact_strings ();
                   1192: 
                   1193:   /* Put all unmarked conses on free list */
                   1194:   {
                   1195:     register struct cons_block *cblk;
                   1196:     register int lim = cons_block_index;
                   1197:     register int num_free = 0, num_used = 0;
                   1198: 
                   1199:     cons_free_list = 0;
                   1200:   
                   1201:     for (cblk = cons_block; cblk; cblk = cblk->next)
                   1202:       {
                   1203:        register int i;
                   1204:        for (i = 0; i < lim; i++)
                   1205:          if (!XMARKBIT (cblk->conses[i].car))
                   1206:            {
                   1207:              XFASTINT (cblk->conses[i].car) = (int) cons_free_list;
                   1208:              num_free++;
                   1209:              cons_free_list = &cblk->conses[i];
                   1210:            }
                   1211:          else
                   1212:            {
                   1213:              num_used++;
                   1214:              XUNMARK (cblk->conses[i].car);
                   1215:            }
                   1216:        lim = CONS_BLOCK_SIZE;
                   1217:       }
                   1218:     total_conses = num_used;
                   1219:     total_free_conses = num_free;
                   1220:   }
                   1221: 
                   1222:   /* Put all unmarked symbols on free list */
                   1223:   {
                   1224:     register struct symbol_block *sblk;
                   1225:     register int lim = symbol_block_index;
                   1226:     register int num_free = 0, num_used = 0;
                   1227: 
                   1228:     symbol_free_list = 0;
                   1229:   
                   1230:     for (sblk = symbol_block; sblk; sblk = sblk->next)
                   1231:       {
                   1232:        register int i;
                   1233:        for (i = 0; i < lim; i++)
                   1234:          if (!XMARKBIT (sblk->symbols[i].plist))
                   1235:            {
                   1236:              XFASTINT (sblk->symbols[i].value) = (int) symbol_free_list;
                   1237:              symbol_free_list = &sblk->symbols[i];
                   1238:              num_free++;
                   1239:            }
                   1240:          else
                   1241:            {
                   1242:              num_used++;
                   1243:              sblk->symbols[i].name
                   1244:                = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name);
                   1245:              XUNMARK (sblk->symbols[i].plist);
                   1246:            }
                   1247:        lim = SYMBOL_BLOCK_SIZE;
                   1248:       }
                   1249:     total_symbols = num_used;
                   1250:     total_free_symbols = num_free;
                   1251:   }
                   1252: 
                   1253: #ifndef standalone
                   1254:   /* Put all unmarked markers on free list.
                   1255:      Dechain each one first from the buffer it points into. */
                   1256:   {
                   1257:     register struct marker_block *mblk;
                   1258:     struct Lisp_Marker *tem1;
                   1259:     register int lim = marker_block_index;
                   1260:     register int num_free = 0, num_used = 0;
                   1261: 
                   1262:     marker_free_list = 0;
                   1263:   
                   1264:     for (mblk = marker_block; mblk; mblk = mblk->next)
                   1265:       {
                   1266:        register int i;
                   1267:        for (i = 0; i < lim; i++)
                   1268:          if (!XMARKBIT (mblk->markers[i].chain))
                   1269:            {
                   1270:              Lisp_Object tem;
                   1271:              tem1 = &mblk->markers[i];  /* tem1 avoids Sun compiler bug */
                   1272:              XSET (tem, Lisp_Marker, tem1);
                   1273:              if (tem1->buffer)
                   1274:                unchain_marker (tem);
                   1275:              XFASTINT (mblk->markers[i].chain) = (int) marker_free_list;
                   1276:              marker_free_list = &mblk->markers[i];
                   1277:              num_free++;
                   1278:            }
                   1279:          else
                   1280:            {
                   1281:              num_used++;
                   1282:              XUNMARK (mblk->markers[i].chain);
                   1283:            }
                   1284:        lim = MARKER_BLOCK_SIZE;
                   1285:       }
                   1286: 
                   1287:     total_markers = num_used;
                   1288:     total_free_markers = num_free;
                   1289:   }
                   1290: 
                   1291:   /* Free all unmarked buffers */
                   1292:   {
                   1293:     register struct buffer *buffer = all_buffers, *prev = 0, *next;
                   1294: 
                   1295:     while (buffer)
                   1296:       if (!XMARKBIT (buffer->name))
                   1297:        {
                   1298:          if (prev)
                   1299:            prev->next = buffer->next;
                   1300:          else
                   1301:            all_buffers = buffer->next;
                   1302:          next = buffer->next;
                   1303:          free (buffer);
                   1304:          buffer = next;
                   1305:        }
                   1306:       else
                   1307:        {
                   1308:          XUNMARK (buffer->name);
                   1309:          prev = buffer, buffer = buffer->next;
                   1310:        }
                   1311:   }
                   1312: 
                   1313: #endif standalone
                   1314: 
                   1315:   /* Free all unmarked vectors */
                   1316:   {
                   1317:     register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next;
                   1318:     total_vector_size = 0;
                   1319: 
                   1320:     while (vector)
                   1321:       if (!(vector->size & ARRAY_MARK_FLAG))
                   1322:        {
                   1323:          if (prev)
                   1324:            prev->next = vector->next;
                   1325:          else
                   1326:            all_vectors = vector->next;
                   1327:          next = vector->next;
                   1328:          free (vector);
                   1329:          vector = next;
                   1330:        }
                   1331:       else
                   1332:        {
                   1333:          vector->size &= ~ARRAY_MARK_FLAG;
                   1334:          total_vector_size += vector->size;
                   1335:          prev = vector, vector = vector->next;
                   1336:        }
                   1337:   }
                   1338: 
                   1339:   /* Free all "large strings" not marked with ARRAY_MARK_FLAG.  */
                   1340:   {
                   1341:     register struct string_block *sb = large_string_blocks, *prev = 0, *next;
                   1342: 
                   1343:     while (sb)
                   1344:       if (!(((struct Lisp_String *)(&sb->chars[0]))->size & ARRAY_MARK_FLAG))
                   1345:        {
                   1346:          if (prev)
                   1347:            prev->next = sb->next;
                   1348:          else
                   1349:            large_string_blocks = sb->next;
                   1350:          next = sb->next;
                   1351:          free (sb);
                   1352:          sb = next;
                   1353:        }
                   1354:       else
                   1355:        {
                   1356:          ((struct Lisp_String *)(&sb->chars[0]))->size
                   1357:            &= ~ARRAY_MARK_FLAG & ~MARKBIT;
                   1358:          total_string_size += ((struct Lisp_String *)(&sb->chars[0]))->size;
                   1359:          prev = sb, sb = sb->next;
                   1360:        }
                   1361:   }
                   1362: }
                   1363: 
                   1364: /* Compactify strings, relocate references to them, and
                   1365:    free any string blocks that become empty.  */
                   1366: 
                   1367: static void
                   1368: compact_strings ()
                   1369: {
                   1370:   /* String block of old strings we are scanning.  */
                   1371:   register struct string_block *from_sb;
                   1372:   /* A preceding string block (or maybe the same one)
                   1373:      where we are copying the still-live strings to.  */
                   1374:   register struct string_block *to_sb;
                   1375:   int pos;
                   1376:   int to_pos;
                   1377: 
                   1378:   to_sb = first_string_block;
                   1379:   to_pos = 0;
                   1380: 
                   1381:   /* Scan each existing string block sequentially, string by string.  */
                   1382:   for (from_sb = first_string_block; from_sb; from_sb = from_sb->next)
                   1383:     {
                   1384:       pos = 0;
                   1385:       /* POS is the index of the next string in the block.  */
                   1386:       while (pos < from_sb->pos)
                   1387:        {
                   1388:          register struct Lisp_String *nextstr
                   1389:            = (struct Lisp_String *) &from_sb->chars[pos];
                   1390: 
                   1391:          register struct Lisp_String *newaddr;
                   1392:          register int size = nextstr->size;
                   1393: 
                   1394:          /* NEXTSTR is the old address of the next string.
                   1395:             Just skip it if it isn't marked.  */
                   1396:          if ((unsigned) size > STRING_BLOCK_SIZE)
                   1397:            {
                   1398:              /* It is marked, so its size field is really a chain of refs.
                   1399:                 Find the end of the chain, where the actual size lives.  */
                   1400:              while ((unsigned) size > STRING_BLOCK_SIZE)
                   1401:                {
                   1402:                  if (size & 1) size ^= MARKBIT | 1;
                   1403:                  size = *(int *)size & ~MARKBIT;
                   1404:                }
                   1405: 
                   1406:              total_string_size += size;
                   1407: 
                   1408:              /* If it won't fit in TO_SB, close it out,
                   1409:                 and move to the next sb.  Keep doing so until
                   1410:                 TO_SB reaches a large enough, empty enough string block.
                   1411:                 We know that TO_SB cannot advance past FROM_SB here
                   1412:                 since FROM_SB is large enough to contain this string.
                   1413:                 Any string blocks skipped here
                   1414:                 will be patched out and freed later.  */
                   1415:              while (to_pos + STRING_FULLSIZE (size)
                   1416:                     > max (to_sb->pos, STRING_BLOCK_SIZE))
                   1417:                {
                   1418:                  to_sb->pos = to_pos;
                   1419:                  to_sb = to_sb->next;
                   1420:                  to_pos = 0;
                   1421:                }
                   1422:              /* Compute new address of this string
                   1423:                 and update TO_POS for the space being used.  */
                   1424:              newaddr = (struct Lisp_String *) &to_sb->chars[to_pos];
                   1425:              to_pos += STRING_FULLSIZE (size);
                   1426: 
                   1427:              /* Copy the string itself to the new place.  */
                   1428:              if (nextstr != newaddr)
                   1429:                bcopy (nextstr, newaddr, size + 1 + sizeof (int));
                   1430: 
                   1431:              /* Go through NEXTSTR's chain of references
                   1432:                 and make each slot in the chain point to
                   1433:                 the new address of this string.  */
                   1434:              size = newaddr->size;
                   1435:              while ((unsigned) size > STRING_BLOCK_SIZE)
                   1436:                {
                   1437:                  register Lisp_Object *objptr;
                   1438:                  if (size & 1) size ^= MARKBIT | 1;
                   1439:                  objptr = (Lisp_Object *)size;
                   1440: 
                   1441:                  size = XFASTINT (*objptr) & ~MARKBIT;
                   1442:                  if (XMARKBIT (*objptr))
                   1443:                    {
                   1444:                      XSET (*objptr, Lisp_String, newaddr);
                   1445:                      XMARK (*objptr);
                   1446:                    }
                   1447:                  else
                   1448:                    XSET (*objptr, Lisp_String, newaddr);
                   1449:                }
                   1450:              /* Store the actual size in the size field.  */
                   1451:              newaddr->size = size;
                   1452:            }
                   1453:          pos += STRING_FULLSIZE (size);
                   1454:        }
                   1455:     }
                   1456: 
                   1457:   /* Close out the last string block still used and free any that follow.  */
                   1458:   to_sb->pos = to_pos;
                   1459:   current_string_block = to_sb;
                   1460: 
                   1461:   from_sb = to_sb->next;
                   1462:   to_sb->next = 0;
                   1463:   while (from_sb)
                   1464:     {
                   1465:       to_sb = from_sb->next;
                   1466:       free (from_sb);
                   1467:       from_sb = to_sb;
                   1468:     }
                   1469: 
                   1470:   /* Free any empty string blocks further back in the chain.
                   1471:      This loop will never free first_string_block, but it is very
                   1472:      unlikely that that one will become empty, so why bother checking?  */
                   1473: 
                   1474:   from_sb = first_string_block;
                   1475:   while (to_sb = from_sb->next)
                   1476:     {
                   1477:       if (to_sb->pos == 0)
                   1478:        {
                   1479:          if (from_sb->next = to_sb->next)
                   1480:            from_sb->next->prev = from_sb;
                   1481:          free (to_sb);
                   1482:        }
                   1483:       else
                   1484:        from_sb = to_sb;
                   1485:     }
                   1486: }
                   1487: 
                   1488: truncate_all_undos ()
                   1489: {
                   1490:   register struct buffer *nextb = all_buffers;
                   1491: 
                   1492:   consing_at_last_truncate = consing_since_gc;
                   1493: 
                   1494:   while (nextb)
                   1495:     {
                   1496:       /* If a buffer's undo list is Qt, that means that undo is
                   1497:         turned off in that buffer.  Calling truncate_undo_list on
                   1498:         Qt tends to return NULL, which effectively turns undo back on.
                   1499:         So don't call truncate_undo_list if undo_list is Qt.  */
                   1500:       if (! EQ (nextb->undo_list, Qt))
                   1501:        nextb->undo_list 
                   1502:          = truncate_undo_list (nextb->undo_list, undo_threshold,
                   1503:                                undo_high_threshold);
                   1504:       nextb = nextb->next;
                   1505:     }
                   1506: }
                   1507: 
                   1508: /* Initialization */
                   1509: 
                   1510: init_alloc_once ()
                   1511: {
                   1512:   /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet!  */
                   1513:   pureptr = 0;
                   1514:   all_vectors = 0;
                   1515:   init_strings ();
                   1516:   init_cons ();
                   1517:   init_symbol ();
                   1518:   init_marker ();
                   1519:   gcprolist = 0;
                   1520:   staticidx = 0;
                   1521:   consing_since_gc = 0;
                   1522:   gc_cons_threshold = 100000;
                   1523: #ifdef VIRT_ADDR_VARIES
                   1524:   malloc_sbrk_unused = 1<<22;  /* A large number */
                   1525:   malloc_sbrk_used = 100000;   /* as reasonable as any number */
                   1526: #endif /* VIRT_ADDR_VARIES */
                   1527: }
                   1528: 
                   1529: init_alloc ()
                   1530: {
                   1531:   gcprolist = 0;
                   1532: }
                   1533: 
                   1534: void
                   1535: syms_of_alloc ()
                   1536: {
                   1537:   memory_exhausted_message = Fcons (build_string ("Memory exhausted"), Qnil);
                   1538:   staticpro (&memory_exhausted_message);
                   1539: 
                   1540:   DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold,
                   1541:     "*Number of bytes of consing between garbage collections.");
                   1542: 
                   1543:   DEFVAR_INT ("pure-bytes-used", &pureptr,
                   1544:     "Number of bytes of sharable Lisp data allocated so far.");
                   1545: 
                   1546: #if 0
                   1547:   DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used,
                   1548:     "Number of bytes of unshared memory allocated in this session.");
                   1549: 
                   1550:   DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused,
                   1551:     "Number of bytes of unshared memory remaining available in this session.");
                   1552: #endif
                   1553: 
                   1554:   DEFVAR_LISP ("purify-flag", &Vpurify_flag,
                   1555:     "Non-nil means loading Lisp code in order to dump an executable.");
                   1556: 
                   1557:   DEFVAR_INT ("undo-threshold", &undo_threshold,
                   1558:     "Keep no more undo information once it exceeds this size.\n\
                   1559: This threshold is applied when garbage collection happens.\n\
                   1560: The size is counted as the number of bytes occupied,\n\
                   1561: which includes both saved text and other data.");
                   1562:   undo_threshold = 15000;
                   1563:   DEFVAR_INT ("undo-high-threshold", &undo_high_threshold,
                   1564:     "Don't keep more than this much size of undo information.\n\
                   1565: A command which pushes past this size is itself forgotten.\n\
                   1566: This threshold is applied when garbage collection happens.\n\
                   1567: The size is counted as the number of bytes occupied,\n\
                   1568: which includes both saved text and other data.");
                   1569:   undo_high_threshold = 20000;
                   1570: 
                   1571:   defsubr (&Scons);
                   1572:   defsubr (&Slist);
                   1573:   defsubr (&Svector);
                   1574:   defsubr (&Smake_list);
                   1575:   defsubr (&Smake_vector);
                   1576:   defsubr (&Smake_string);
                   1577:   defsubr (&Smake_symbol);
                   1578:   defsubr (&Smake_marker);
                   1579:   defsubr (&Spurecopy);
                   1580:   defsubr (&Sgarbage_collect);
                   1581: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.