Annotation of researchv10dc/cmd/gcc/alloc.c, revision 1.1.1.1

1.1       root        1: /* Storage allocation and gc for GNU Emacs Lisp interpreter.
                      2:    Copyright (C) 1985 Richard M. Stallman.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: GNU Emacs General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU Emacs so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: 
                     24: /* Number of bytes of consing done since the last gc */
                     25: int consing_since_gc;
                     26: 
                     27: /* Number of bytes of consing since gc before another gc should be done. */
                     28: int gc_cons_threshold;
                     29: 
                     30: /* Nonzero during gc */
                     31: int gc_in_progress;
                     32: 
                     33: #ifndef VIRT_ADDR_VARIES
                     34: /* Address below which pointers should not be traced */
                     35: extern char edata[];
                     36: #endif /* VIRT_ADDR_VARIES */
                     37: 
                     38: #ifndef VIRT_ADDR_VARIES
                     39: extern
                     40: #endif /* VIRT_ADDR_VARIES */
                     41:  int malloc_sbrk_used;
                     42: 
                     43: #ifndef VIRT_ADDR_VARIES
                     44: extern
                     45: #endif /* VIRT_ADDR_VARIES */
                     46:  int malloc_sbrk_unused;
                     47: 
                     48: /* Non-nil means defun should do purecopy on the function definition */
                     49: Lisp_Object Vpurify_flag;
                     50: 
                     51: int pure[PURESIZE / sizeof (int)] = {0,};   /* Force it into data space! */
                     52: 
                     53: #define PUREBEG (char *) pure
                     54: 
                     55: /* Index in pure at which next pure object will be allocated. */
                     56: int pureptr;
                     57: 
                     58: Lisp_Object
                     59: malloc_warning_1 (str)
                     60:      Lisp_Object str;
                     61: {
                     62:   return Fprinc (str, Vstandard_output);
                     63: }
                     64: 
                     65: /* malloc calls this if it finds we are near exhausting storage */
                     66: malloc_warning (str)
                     67:      char *str;
                     68: {
                     69:   Lisp_Object val;
                     70:   val = build_string (str);
                     71:   internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val);
                     72: }
                     73: 
                     74: /* Called if malloc returns zero */
                     75: memory_full ()
                     76: {
                     77:   error ("Memory exhausted");
                     78: }
                     79: 
                     80: /* like malloc and realloc but check for no memory left */
                     81: 
                     82: long *
                     83: xmalloc (size)
                     84:      int size;
                     85: {
                     86:   long *val = (long *) malloc (size);
                     87:   if (!val) memory_full ();
                     88:   return val;
                     89: }
                     90: 
                     91: long *
                     92: xrealloc (block, size)
                     93:      long *block;
                     94:      int size;
                     95: {
                     96:   long *val = (long *) realloc (block, size);
                     97:   if (!val) memory_full ();
                     98:   return val;
                     99: }
                    100: 
                    101: /* Allocation of cons cells */
                    102: /* We store cons cells inside of cons_blocks, allocating a new
                    103:  cons_block with malloc whenever necessary.  Cons cells reclaimed by
                    104:  GC are put on a free list to be reallocated before allocating
                    105:  any new cons cells from the latest cons_block.
                    106: 
                    107:  Each cons_block is just under 1020 bytes long,
                    108:  since malloc really allocates in units of powers of two
                    109:  and uses 4 bytes for its own overhead. */
                    110: 
                    111: #define CONS_BLOCK_SIZE \
                    112:   ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons))
                    113: 
                    114: struct cons_block
                    115:   {
                    116:     struct cons_block *next;
                    117:     struct Lisp_Cons conses[CONS_BLOCK_SIZE];
                    118:   };
                    119: 
                    120: struct cons_block *cons_block;
                    121: int cons_block_index;
                    122: 
                    123: struct Lisp_Cons *cons_free_list;
                    124: 
                    125: void
                    126: init_cons ()
                    127: {
                    128:   cons_block = (struct cons_block *) malloc (sizeof (struct cons_block));
                    129:   cons_block->next = 0;
                    130:   bzero (cons_block->conses, sizeof cons_block->conses);
                    131:   cons_block_index = 0;
                    132:   cons_free_list = 0;
                    133: }
                    134: 
                    135: /* Explicitly free a cons cell.  */
                    136: free_cons (ptr)
                    137:      struct Lisp_Cons *ptr;
                    138: {
                    139:   XSETCONS (ptr->car, cons_free_list);
                    140:   cons_free_list = ptr;
                    141: }
                    142: 
                    143: DEFUN ("cons", Fcons, Scons, 2, 2, 0,
                    144:   "Create a new cons, give it CAR and CDR as components, and return it.")
                    145:   (car, cdr)
                    146:      Lisp_Object car, cdr;
                    147: {
                    148:   register Lisp_Object val;
                    149: 
                    150:   if (cons_free_list)
                    151:     {
                    152:       XSET (val, Lisp_Cons, cons_free_list);
                    153:       cons_free_list = XCONS (cons_free_list->car);
                    154:     }
                    155:   else
                    156:     {
                    157:       if (cons_block_index == CONS_BLOCK_SIZE)
                    158:        {
                    159:          register struct cons_block *new = (struct cons_block *) malloc (sizeof (struct cons_block));
                    160:          if (!new) memory_full ();
                    161:          new->next = cons_block;
                    162:          cons_block = new;
                    163:          cons_block_index = 0;
                    164:        }
                    165:       XSET (val, Lisp_Cons, &cons_block->conses[cons_block_index++]);
                    166:     }
                    167:   XCONS (val)->car = car;
                    168:   XCONS (val)->cdr = cdr;
                    169:   consing_since_gc += sizeof (struct Lisp_Cons);
                    170:   return val;
                    171: }
                    172: 
                    173: DEFUN ("list", Flist, Slist, 0, MANY, 0,
                    174:   "Return a newly created list whose elements are the arguments (any number).")
                    175:   (nargs, args)
                    176:      int nargs;
                    177:      Lisp_Object *args;
                    178: {
                    179:   Lisp_Object len, val, val_tail;
                    180: 
                    181:   XFASTINT (len) = nargs;
                    182:   val = Fmake_list (len, Qnil);
                    183:   val_tail = val;
                    184:   while (!NULL (val_tail))
                    185:     {
                    186:       XCONS (val_tail)->car = *args++;
                    187:       val_tail = XCONS (val_tail)->cdr;
                    188:     }
                    189:   return val;
                    190: }
                    191: 
                    192: DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
                    193:   "Return a newly created list of length LENGTH, with each element being INIT.")
                    194:   (length, init)
                    195:      Lisp_Object length, init;
                    196: {
                    197:   register Lisp_Object val;
                    198:   register int size;
                    199: 
                    200:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    201:     length = wrong_type_argument (Qnatnump, length);
                    202:   size = XINT (length);
                    203: 
                    204:   val = Qnil;
                    205:   while (size-- > 0)
                    206:     val = Fcons (init, val);
                    207:   return val;
                    208: }
                    209: 
                    210: /* Allocation of vectors */
                    211: 
                    212: struct Lisp_Vector *all_vectors;
                    213: 
                    214: DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
                    215:   "Return a newly created vector of length LENGTH, with each element being INIT.")
                    216:   (length, init)
                    217:      Lisp_Object length, init;
                    218: {
                    219:   register int sizei, index;
                    220:   register Lisp_Object vector;
                    221: 
                    222:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    223:     length = wrong_type_argument (Qnatnump, length);
                    224:   sizei = XINT (length);
                    225: 
                    226:   XSET (vector, Lisp_Vector,
                    227:        (struct Lisp_Vector *) malloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)));
                    228:   consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object);
                    229:   if (!XVECTOR (vector))
                    230:     memory_full ();
                    231: 
                    232:   XVECTOR (vector)->size = sizei;
                    233:   XVECTOR (vector)->next = all_vectors;
                    234:   all_vectors = XVECTOR (vector);
                    235: 
                    236:   for (index = 0; index < sizei; index++)
                    237:     XVECTOR (vector)->contents[index] = init;
                    238: 
                    239:   return vector;
                    240: }
                    241: 
                    242: DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
                    243:   "Return a newly created vector with our arguments (any number) as its elements.")
                    244:   (nargs, args)
                    245:      int nargs;
                    246:      Lisp_Object *args;
                    247: {
                    248:   register Lisp_Object len, val;
                    249:   register int index;
                    250:   register struct Lisp_Vector *p;
                    251: 
                    252:   XFASTINT (len) = nargs;
                    253:   val = Fmake_vector (len, Qnil);
                    254:   p = XVECTOR (val);
                    255:   for (index = 0; index < nargs; index++)
                    256:     p->contents[index] = args[index];
                    257:   return val;
                    258: }
                    259: 
                    260: /* Allocation of symbols.
                    261:  Just like allocation of conses!
                    262: 
                    263:  Each symbol_block is just under 1020 bytes long,
                    264:  since malloc really allocates in units of powers of two
                    265:  and uses 4 bytes for its own overhead. */
                    266: 
                    267: #define SYMBOL_BLOCK_SIZE \
                    268:   ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
                    269: 
                    270: struct symbol_block
                    271:   {
                    272:     struct symbol_block *next;
                    273:     struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
                    274:   };
                    275: 
                    276: struct symbol_block *symbol_block;
                    277: int symbol_block_index;
                    278: 
                    279: struct Lisp_Symbol *symbol_free_list;
                    280: 
                    281: void
                    282: init_symbol ()
                    283: {
                    284:   symbol_block = (struct symbol_block *) malloc (sizeof (struct symbol_block));
                    285:   symbol_block->next = 0;
                    286:   bzero (symbol_block->symbols, sizeof symbol_block->symbols);
                    287:   symbol_block_index = 0;
                    288:   symbol_free_list = 0;
                    289: }
                    290: 
                    291: DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
                    292:   "Return a newly allocated uninterned symbol whose name is NAME.\n\
                    293: Its value and function definition are void, and its property list is NIL.")
                    294:   (str)
                    295:      Lisp_Object str;
                    296: {
                    297:   register Lisp_Object val;
                    298: 
                    299:   CHECK_STRING (str, 0);
                    300: 
                    301:   if (symbol_free_list)
                    302:     {
                    303:       XSET (val, Lisp_Symbol, symbol_free_list);
                    304:       symbol_free_list = XSYMBOL (symbol_free_list->value);
                    305:     }
                    306:   else
                    307:     {
                    308:       if (symbol_block_index == SYMBOL_BLOCK_SIZE)
                    309:        {
                    310:          struct symbol_block *new = (struct symbol_block *) malloc (sizeof (struct symbol_block));
                    311:          if (!new) memory_full ();
                    312:          new->next = symbol_block;
                    313:          symbol_block = new;
                    314:          symbol_block_index = 0;
                    315:        }
                    316:       XSET (val, Lisp_Symbol, &symbol_block->symbols[symbol_block_index++]);
                    317:     }
                    318:   XSYMBOL (val)->name = XSTRING (str);
                    319:   XSYMBOL (val)->plist = Qnil;
                    320:   XSYMBOL (val)->value = Qunbound;
                    321:   XSYMBOL (val)->function = Qunbound;
                    322:   XSYMBOL (val)->next = 0;
                    323:   consing_since_gc += sizeof (struct Lisp_Symbol);
                    324:   return val;
                    325: }
                    326: 
                    327: /* Allocation of markers.
                    328:  Works like allocation of conses. */
                    329: 
                    330: #define MARKER_BLOCK_SIZE \
                    331:   ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker))
                    332: 
                    333: struct marker_block
                    334:   {
                    335:     struct marker_block *next;
                    336:     struct Lisp_Marker markers[MARKER_BLOCK_SIZE];
                    337:   };
                    338: 
                    339: struct marker_block *marker_block;
                    340: int marker_block_index;
                    341: 
                    342: struct Lisp_Marker *marker_free_list;
                    343: 
                    344: void
                    345: init_marker ()
                    346: {
                    347:   marker_block = (struct marker_block *) malloc (sizeof (struct marker_block));
                    348:   marker_block->next = 0;
                    349:   bzero (marker_block->markers, sizeof marker_block->markers);
                    350:   marker_block_index = 0;
                    351:   marker_free_list = 0;
                    352: }
                    353: 
                    354: DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
                    355:   "Return a newly allocated marker which does not point at any place.")
                    356:   ()
                    357: {
                    358:   register Lisp_Object val;
                    359: 
                    360:   if (marker_free_list)
                    361:     {
                    362:       XSET (val, Lisp_Marker, marker_free_list);
                    363:       marker_free_list = XMARKER (marker_free_list->chain);
                    364:     }
                    365:   else
                    366:     {
                    367:       if (marker_block_index == MARKER_BLOCK_SIZE)
                    368:        {
                    369:          struct marker_block *new = (struct marker_block *) malloc (sizeof (struct marker_block));
                    370:          if (!new) memory_full ();
                    371:          new->next = marker_block;
                    372:          marker_block = new;
                    373:          marker_block_index = 0;
                    374:        }
                    375:       XSET (val, Lisp_Marker, &marker_block->markers[marker_block_index++]);
                    376:     }
                    377:   XMARKER (val)->buffer = 0;
                    378:   XMARKER (val)->bufpos = 0;
                    379:   XMARKER (val)->modified = 0;
                    380:   XMARKER (val)->chain = Qnil;
                    381:   consing_since_gc += sizeof (struct Lisp_Marker);
                    382:   return val;
                    383: }
                    384: 
                    385: /* Allocation of strings */
                    386: 
                    387: /* Strings reside inside of string_blocks.  The entire data of the string,
                    388:  both the size and the contents, live in part of the `chars' component of a string_block.
                    389:  The `pos' component is the index within `chars' of the first free byte */
                    390: 
                    391: /* String blocks contain this many bytes.
                    392:   Power of 2, minus 4 for malloc overhead. */
                    393: #define STRING_BLOCK_SIZE (8188 - sizeof (struct string_block_head))
                    394: 
                    395: /* A string bigger than this gets its own specially-made string block
                    396:  if it doesn't fit in the current one. */
                    397: #define STRING_BLOCK_OUTSIZE 1024
                    398: 
                    399: struct string_block_head
                    400:   {
                    401:     struct string_block *next;
                    402:     int pos;
                    403:   };
                    404: 
                    405: struct string_block
                    406:   {
                    407:     struct string_block *next;
                    408:     int pos;
                    409:     char chars[STRING_BLOCK_SIZE];
                    410:   };
                    411: 
                    412: /* This points to the string block we are now allocating strings in
                    413:  which is also the beginning of the chain of all string blocks ever made */
                    414: 
                    415: struct string_block *current_string_block;
                    416: 
                    417: void
                    418: init_strings ()
                    419: {
                    420:   current_string_block = (struct string_block *) malloc (sizeof (struct string_block));
                    421:   consing_since_gc += sizeof (struct string_block);
                    422:   current_string_block->next = 0;
                    423:   current_string_block->pos = 0;
                    424: }
                    425: 
                    426: static Lisp_Object make_zero_string ();
                    427: 
                    428: DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0,
                    429:   "Return a newly created string of length LENGTH, with each element being INIT.\n\
                    430: Both LENGTH and INIT must be numbers.")
                    431:   (length, init)
                    432:      Lisp_Object length, init;
                    433: {
                    434:   if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
                    435:     length = wrong_type_argument (Qnatnump, length);
                    436:   CHECK_NUMBER (init, 1);
                    437:   return make_zero_string (XINT (length), XINT (init));
                    438: }
                    439: 
                    440: Lisp_Object
                    441: make_string (contents, length)
                    442:      char *contents;
                    443:      int length;
                    444: {
                    445:   Lisp_Object val;
                    446:   val = make_zero_string (length, 0);
                    447:   bcopy (contents, XSTRING (val)->data, length);
                    448:   return val;
                    449: }
                    450: 
                    451: Lisp_Object
                    452: build_string (str)
                    453:      char *str;
                    454: {
                    455:   return make_string (str, strlen (str));
                    456: }
                    457: 
                    458: static Lisp_Object
                    459: make_zero_string (length, init)
                    460:      int length;
                    461:      register int init;
                    462: {
                    463:   register Lisp_Object val;
                    464:   register int fullsize = length + sizeof (int);
                    465:   register unsigned char *p, *end;
                    466: 
                    467:   if (length < 0) abort ();
                    468: 
                    469:   /* Round `fullsize' up to multiple of size of int; also add one for terminating zero */
                    470:   fullsize += sizeof (int);
                    471:   fullsize &= ~(sizeof (int) - 1);
                    472: 
                    473:   if (fullsize <= STRING_BLOCK_SIZE - current_string_block->pos)
                    474:     /* This string can fit in the current string block */
                    475:     {
                    476:       XSET (val, Lisp_String,
                    477:            (struct Lisp_String *) (current_string_block->chars + current_string_block->pos));
                    478:       current_string_block->pos += fullsize;
                    479:     }
                    480:   else if (fullsize > STRING_BLOCK_OUTSIZE)
                    481:     /* This string gets its own string block */
                    482:     {
                    483:       struct string_block *new = (struct string_block *) malloc (sizeof (struct string_block_head) + fullsize);
                    484:       if (!new) memory_full ();
                    485:       consing_since_gc += sizeof (struct string_block_head) + fullsize;
                    486:       new->pos = fullsize;
                    487:       new->next = current_string_block->next;
                    488:       current_string_block->next = new;
                    489:       XSET (val, Lisp_String,
                    490:            (struct Lisp_String *) ((struct string_block_head *)new + 1));
                    491:     }
                    492:   else
                    493:     /* Make a new current string block and start it off with this string */
                    494:     {
                    495:       struct string_block *new = (struct string_block *) malloc (sizeof (struct string_block));
                    496:       if (!new) memory_full ();
                    497:       consing_since_gc += sizeof (struct string_block);
                    498:       new->next = current_string_block;
                    499:       current_string_block = new;
                    500:       new->pos = fullsize;
                    501:       XSET (val, Lisp_String,
                    502:            (struct Lisp_String *) current_string_block->chars);
                    503:     }
                    504:     
                    505:   XSTRING (val)->size = length;
                    506:   p = XSTRING (val)->data;
                    507:   end = p + XSTRING (val)->size;
                    508:   while (p != end)
                    509:     *p++ = init;
                    510:   *p = 0;
                    511: 
                    512:   return val;
                    513: }
                    514: 
                    515: /* Must get an error if pure storage is full,
                    516:  since if it cannot hold a large string
                    517:  it may be able to hold conses that point to that string;
                    518:  then the string is not protected from gc. */
                    519: 
                    520: Lisp_Object
                    521: make_pure_string (data, length)
                    522:      char *data;
                    523:      int length;
                    524: {
                    525:   Lisp_Object new;
                    526:   int size = sizeof (int) + length + 1;
                    527: 
                    528:   if (pureptr + size > PURESIZE)
                    529:     error ("Pure Lisp storage exhausted");
                    530:   XSET (new, Lisp_String, PUREBEG + pureptr);
                    531:   XSTRING (new)->size = length;
                    532:   bcopy (data, XSTRING (new)->data, length);
                    533:   XSTRING (new)->data[length] = 0;
                    534:   pureptr += (size + sizeof (int) - 1)
                    535:             / sizeof (int) * sizeof (int);
                    536:   return new;
                    537: }
                    538: 
                    539: Lisp_Object
                    540: pure_cons (car, cdr)
                    541:      Lisp_Object car, cdr;
                    542: {
                    543:   Lisp_Object new;
                    544: 
                    545:   if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE)
                    546:     error ("Pure Lisp storage exhausted");
                    547:   XSET (new, Lisp_Cons, PUREBEG + pureptr);
                    548:   pureptr += sizeof (struct Lisp_Cons);
                    549:   XCONS (new)->car = Fpurecopy (car);
                    550:   XCONS (new)->cdr = Fpurecopy (cdr);
                    551:   return new;
                    552: }
                    553: 
                    554: Lisp_Object
                    555: make_pure_vector (len)
                    556:      int len;
                    557: {
                    558:   Lisp_Object new;
                    559:   int size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object);
                    560: 
                    561:   if (pureptr + size > PURESIZE)
                    562:     error ("Pure Lisp storage exhausted");
                    563: 
                    564:   XSET (new, Lisp_Vector, PUREBEG + pureptr);
                    565:   pureptr += size;
                    566:   XVECTOR (new)->size = len;
                    567:   return new;
                    568: }
                    569: 
                    570: DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
                    571:   "Make a copy of OBJECT in pure storage.\n\
                    572: Recursively copies contents of vectors and cons cells.\n\
                    573: Does not copy symbols.")
                    574:   (obj)
                    575:      Lisp_Object obj;
                    576: {
                    577:   Lisp_Object new, tem;
                    578:   int i;
                    579: 
                    580: #ifndef VIRT_ADDR_VARIES
                    581:   /* Need not trace pointers to pure storage */
                    582:   if (XUINT (obj) < (unsigned int) edata && XUINT (obj) >= 0)
                    583:     return obj;
                    584: #else /* VIRT_ADDR_VARIES */
                    585:   if (XUINT (obj) < (unsigned int) ((char *) pure + PURESIZE)
                    586:       && XUINT (obj) >= (unsigned int) pure)
                    587:     return obj;
                    588: #endif /* VIRT_ADDR_VARIES */
                    589: 
                    590: #ifdef SWITCH_ENUM_BUG
                    591:   switch ((int) XTYPE (obj))
                    592: #else
                    593:   switch (XTYPE (obj))
                    594: #endif
                    595:     {
                    596:     case Lisp_Marker:
                    597:       error ("Attempt to copy a marker to pure storage");
                    598: 
                    599:     case Lisp_Cons:
                    600:       return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr);
                    601: 
                    602:     case Lisp_String:
                    603:       return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size);
                    604: 
                    605:     case Lisp_Vector:
                    606:       new = make_pure_vector (XVECTOR (obj)->size);
                    607:       for (i = 0; i < XVECTOR (obj)->size; i++)
                    608:        {
                    609:          tem = XVECTOR (obj)->contents[i];
                    610:          XVECTOR (new)->contents[i] = Fpurecopy (tem);
                    611:        }
                    612:       return new;
                    613: 
                    614:     default:
                    615:       return obj;
                    616:     }
                    617: }
                    618: 
                    619: /* Recording what needs to be marked for gc.  */
                    620: 
                    621: struct gcpro *gcprolist;
                    622: 
                    623: #define NSTATICS 100
                    624: 
                    625: char staticvec1[NSTATICS * sizeof (Lisp_Object *)] = {0};
                    626: 
                    627: int staticidx = 0;
                    628: 
                    629: #define staticvec ((Lisp_Object **) staticvec1)
                    630: 
                    631: /* Put an entry in staticvec, pointing at the variable whose address is given */
                    632: 
                    633: void
                    634: staticpro (varaddress)
                    635:      Lisp_Object *varaddress;
                    636: {
                    637:   staticvec[staticidx++] = varaddress;
                    638:   if (staticidx >= NSTATICS)
                    639:     abort ();
                    640: }
                    641: 
                    642: struct catchtag
                    643:   {
                    644:     Lisp_Object tag;
                    645:     Lisp_Object val;
                    646:     struct catchtag *next;
                    647: /*    jmp_buf jmp;  /* We don't need this for GC purposes */
                    648:   };
                    649: 
                    650: extern struct catchtag *catchlist;
                    651: 
                    652: struct backtrace
                    653:   {
                    654:     struct backtrace *next;
                    655:     Lisp_Object *function;
                    656:     Lisp_Object *args; /* Points to vector of args. */
                    657:     int nargs;         /* length of vector */
                    658:               /* if nargs is UNEVALLED, args points to slot holding list of unevalled args */
                    659:     char evalargs;
                    660:   };
                    661: 
                    662: extern struct backtrace *backtrace_list;
                    663: 
                    664: /* On vector, means it has been marked.
                    665:  On string, means it has been copied.  */
                    666: static int most_negative_fixnum;
                    667: 
                    668: /* On string, means do not copy it.
                    669:  This is set in all copies, and perhaps will be used
                    670:  to indicate strings that there is no need to copy.  */
                    671: static int dont_copy_flag;
                    672: 
                    673: int total_conses, total_markers, total_symbols, total_string_size, total_vector_size;
                    674: int total_free_conses, total_free_markers, total_free_symbols;
                    675: 
                    676: /* Garbage collection: mark and sweep, except copy strings. */
                    677: static Lisp_Object mark_object ();
                    678: static void clear_marks (), gc_sweep ();
                    679: 
                    680: DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
                    681:   "Reclaim storage for Lisp objects no longer needed.\n\
                    682: Returns info on amount of space in use:\n\
                    683:  ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\
                    684:   (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS)\n\
                    685: Garbage collection happens automatically if you cons more than\n\
                    686: gc-cons-threshold  bytes of Lisp data since previous garbage collection.")
                    687:   ()
                    688: {
                    689:   struct string_block *old_string_block;
                    690: 
                    691:   register struct gcpro *tail;
                    692:   register struct specbinding *bind;
                    693:   struct catchtag *catch;
                    694:   struct handler *handler;
                    695:   register struct backtrace *backlist;
                    696:   register Lisp_Object tem;
                    697:   char *omessage = minibuf_message;
                    698: 
                    699:   register int i;
                    700: 
                    701:   if (!noninteractive)
                    702:     message1 ("Garbage collecting...");
                    703: 
                    704:   /* Don't keep command history around forever */
                    705:   tem = Fnthcdr (make_number (30), Vcommand_history);
                    706:   if (LISTP (tem))
                    707:     XCONS (tem)->cdr = Qnil;
                    708: 
                    709:   gc_in_progress = 1;
                    710: 
                    711:   clear_marks ();
                    712:   old_string_block = current_string_block;
                    713:   current_string_block = 0;
                    714:   total_string_size = 0;
                    715:   init_strings ();
                    716: 
                    717:   for (tail = gcprolist; tail; tail = tail->next)
                    718:     {
                    719:       for (i = 0; i < tail->nvars; i++)
                    720:        {
                    721:          tem = tail->var[i];
                    722:          tail->var[i] = mark_object (tem);
                    723:        }
                    724:     }
                    725:   for (i = 0; i < staticidx; i++)
                    726:     {
                    727:       tem = *staticvec[i];
                    728:       *staticvec[i] = mark_object (tem);
                    729:     }
                    730:   for (bind = specpdl; bind != specpdl_ptr; bind++)
                    731:     {
                    732:       bind->symbol = mark_object (bind->symbol);
                    733:       bind->old_value = mark_object (bind->old_value);
                    734:     }
                    735:   for (catch = catchlist; catch; catch = catch->next)
                    736:     {
                    737:       catch->tag = mark_object (catch->tag);
                    738:       catch->val = mark_object (catch->val);
                    739:     }  
                    740:   for (handler = handlerlist; handler; handler = handler->next)
                    741:     {
                    742:       handler->handler = mark_object (handler->handler);
                    743:       handler->var = mark_object (handler->var);
                    744:     }  
                    745:   for (backlist = backtrace_list; backlist; backlist = backlist->next)
                    746:     {
                    747:       tem = *backlist->function;
                    748:       *backlist->function = mark_object (tem);
                    749:       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
                    750:        {
                    751:          tem = *backlist->args;
                    752:          *backlist->args = mark_object (tem);
                    753:        }
                    754:       else
                    755:        for (i = 0; i < backlist->nargs; i++)
                    756:          {
                    757:            tem = backlist->args[i];
                    758:            backlist->args[i] = mark_object (tem);
                    759:          }
                    760:     }  
                    761: 
                    762:   gc_sweep (old_string_block);
                    763: 
                    764:   clear_marks ();
                    765:   gc_in_progress = 0;
                    766: 
                    767:   consing_since_gc = 0;
                    768:   if (gc_cons_threshold < 10000)
                    769:     gc_cons_threshold = 10000;
                    770: 
                    771:   if (omessage)
                    772:     message1 (omessage);
                    773:   else if (!noninteractive)
                    774:     message1 ("Garbage collecting...done");
                    775:   
                    776:   return Fcons (Fcons (make_number (total_conses),
                    777:                       make_number (total_free_conses)),
                    778:                Fcons (Fcons (make_number (total_symbols),
                    779:                              make_number (total_free_symbols)),
                    780:                       Fcons (Fcons (make_number (total_markers),
                    781:                                     make_number (total_free_markers)),
                    782:                              Fcons (make_number (total_string_size),
                    783:                                     Fcons (make_number (total_vector_size),
                    784:                                            Qnil)))));
                    785: }
                    786: 
                    787: static void
                    788: clear_marks ()
                    789: {
                    790:   /* Clear marks on all strings */
                    791:   {
                    792:     register struct string_block *csb;
                    793:     register int pos;
                    794: 
                    795:     for (csb = current_string_block; csb; csb = csb->next)
                    796:       {
                    797:        pos = 0;
                    798:        while (pos < csb->pos)
                    799:          {
                    800:            register struct Lisp_String *nextstr
                    801:              = (struct Lisp_String *) &csb->chars[pos];
                    802:            register int fullsize;
                    803: 
                    804:            nextstr->size &= ~dont_copy_flag;
                    805:            fullsize = nextstr->size + sizeof (int);    
                    806:            
                    807:            fullsize += sizeof (int);
                    808:            fullsize &= ~(sizeof (int) - 1);
                    809:            pos += fullsize;
                    810:          }
                    811:       }
                    812:   }
                    813:   /* Clear marks on all conses */
                    814:   {
                    815:     register struct cons_block *cblk;
                    816:     register int lim = cons_block_index;
                    817:   
                    818:     for (cblk = cons_block; cblk; cblk = cblk->next)
                    819:       {
                    820:        register int i;
                    821:        for (i = 0; i < lim; i++)
                    822:          XUNMARK (cblk->conses[i].car);
                    823:        lim = CONS_BLOCK_SIZE;
                    824:       }
                    825:   }
                    826:   /* Clear marks on all symbols */
                    827:   {
                    828:     register struct symbol_block *sblk;
                    829:     register int lim = symbol_block_index;
                    830:   
                    831:     for (sblk = symbol_block; sblk; sblk = sblk->next)
                    832:       {
                    833:        register int i;
                    834:        for (i = 0; i < lim; i++)
                    835:          XUNMARK (sblk->symbols[i].plist);
                    836:        lim = SYMBOL_BLOCK_SIZE;
                    837:       }
                    838:   }
                    839:   /* Clear marks on all markers */
                    840:   {
                    841:     register struct marker_block *sblk;
                    842:     register int lim = marker_block_index;
                    843:   
                    844:     for (sblk = marker_block; sblk; sblk = sblk->next)
                    845:       {
                    846:        register int i;
                    847:        for (i = 0; i < lim; i++)
                    848:          XUNMARK (sblk->markers[i].chain);
                    849:        lim = MARKER_BLOCK_SIZE;
                    850:       }
                    851:   }
                    852:   /* Clear mark bits on all buffers */
                    853:   {
                    854:     register struct buffer *nextb = all_buffers;
                    855: 
                    856:     while (nextb)
                    857:       {
                    858:        XUNMARK (nextb->name);
                    859:        nextb = nextb->next;
                    860:       }
                    861:   }
                    862: }
                    863: 
                    864: /* Mark one Lisp object, and recursively mark all the objects it points to
                    865:  if this is the first time it is being marked.
                    866:  If the object is a string, it is copied (once, only) and the copy is returned.
                    867:  The original string's `size' is set to a value in which 1<<31 is set
                    868:    and the rest of which is the string address shifted right by one.
                    869:  If the object is not a string, it is returned unchanged. */
                    870: 
                    871: static Lisp_Object
                    872: mark_object (obj)
                    873:      Lisp_Object obj;
                    874: {
                    875:   Lisp_Object original;
                    876: 
                    877:   original = obj;
                    878: 
                    879:  loop:
                    880: #ifndef VIRT_ADDR_VARIES
                    881:   /* Need not trace pointers to pure storage */
                    882:   if (XUINT (obj) < (unsigned int) edata && XUINT (obj) >= 0)
                    883:     return original;
                    884: #else /* VIRT_ADDR_VARIES */
                    885:   if (XUINT (obj) < (unsigned int) ((char *) pure + PURESIZE)
                    886:       && XUINT (obj) >= (unsigned int) pure)
                    887:     return original;
                    888: #endif /* VIRT_ADDR_VARIES */
                    889: 
                    890: #ifdef SWITCH_ENUM_BUG
                    891:   switch ((int) XGCTYPE (obj))
                    892: #else
                    893:   switch (XGCTYPE (obj))
                    894: #endif
                    895:     {
                    896:     case Lisp_String:
                    897:       {
                    898:        register struct Lisp_String *ptr = XSTRING (obj);
                    899:        Lisp_Object tem;
                    900: 
                    901:        if (ptr->size & most_negative_fixnum)
                    902:          {
                    903:            XSETSTRING (obj, (struct Lisp_String *) (ptr->size & ~most_negative_fixnum));
                    904:            return obj;
                    905:          }
                    906:        if (ptr->size & dont_copy_flag)
                    907:          return obj;
                    908:        total_string_size += ptr->size;
                    909:        tem = make_string (ptr->data, ptr->size);
                    910:        ptr->size = most_negative_fixnum | XINT (tem);
                    911:        XSTRING (tem)->size |= dont_copy_flag;
                    912:        return tem;
                    913:       }
                    914: 
                    915:     case Lisp_Vector:
                    916:     case Lisp_Window:
                    917:     case Lisp_Process:
                    918:       {
                    919:        register struct Lisp_Vector *ptr = XVECTOR (obj);
                    920:        register int size = ptr->size;
                    921:        register int i;
                    922:        Lisp_Object tem;
                    923: 
                    924:        if (size & most_negative_fixnum) break;   /* Already marked */
                    925:        ptr->size |= most_negative_fixnum; /* Else mark it */
                    926:        for (i = 0; i < size; i++)     /* and then mark its elements */
                    927:          {
                    928:            tem = ptr->contents[i];
                    929:            ptr->contents[i] = mark_object (tem);
                    930:          }
                    931:       }
                    932:       break;
                    933: 
                    934:     case Lisp_Temp_Vector:
                    935:       {
                    936:        register struct Lisp_Vector *ptr = XVECTOR (obj);
                    937:        register int size = ptr->size;
                    938:        register int i;
                    939:        Lisp_Object tem;
                    940: 
                    941:        for (i = 0; i < size; i++)     /* and then mark its elements */
                    942:          {
                    943:            tem = ptr->contents[i];
                    944:            ptr->contents[i] = mark_object (tem);
                    945:          }
                    946:       }
                    947:       break;
                    948: 
                    949:     case Lisp_Symbol:
                    950:       {
                    951:        register struct Lisp_Symbol *ptr = XSYMBOL (obj);
                    952:        struct Lisp_Symbol *ptrx;
                    953:        Lisp_Object tem;
                    954: 
                    955:        if (XMARKBIT (ptr->plist)) break;
                    956:        XMARK (ptr->plist);
                    957:        XSET (tem, Lisp_String, ptr->name);
                    958:        tem = mark_object (tem);
                    959:        ptr->name = XSTRING (tem);
                    960:        ptr->value = mark_object (ptr->value);
                    961:        ptr->function = mark_object (ptr->function);
                    962:        tem = ptr->plist;
                    963:        XUNMARK (tem);
                    964:        ptr->plist = mark_object (tem);
                    965:        XMARK (ptr->plist);
                    966:        ptr = ptr->next;
                    967:        if (ptr)
                    968:          {
                    969:            ptrx = ptr;         /* Use pf ptrx avoids compiled bug on Sun */
                    970:            XSETSYMBOL (obj, ptrx);
                    971:            goto loop;
                    972:          }
                    973:       }
                    974:       break;
                    975: 
                    976:     case Lisp_Marker:
                    977:       XMARK (XMARKER (obj)->chain);
                    978:       /* DO NOT mark thru the marker's chain.
                    979:         The buffer's markers chain does not preserve markers from gc;
                    980:         instead, markers are removed from the chain when they are freed by gc. */
                    981:       break;
                    982: 
                    983:     case Lisp_Cons:
                    984:     case Lisp_Buffer_Local_Value:
                    985:     case Lisp_Some_Buffer_Local_Value:
                    986:       {
                    987:        Lisp_Object tem;
                    988:        register struct Lisp_Cons *ptr = XCONS (obj);
                    989:        if (XMARKBIT (ptr->car)) break;
                    990:        tem = ptr->car;
                    991:        XMARK (ptr->car);
                    992:        ptr->car = mark_object (tem);
                    993:        XMARK (ptr->car);
                    994:        if (XGCTYPE (ptr->cdr) != Lisp_String)
                    995:          {
                    996:            obj = ptr->cdr;
                    997:            goto loop;
                    998:          }
                    999:        ptr->cdr = mark_object (ptr->cdr);
                   1000:       }
                   1001:       break;
                   1002:     
                   1003:     case Lisp_Objfwd:
                   1004:       *XOBJFWD (obj) = mark_object (*XOBJFWD (obj));
                   1005:       break;
                   1006: 
                   1007:     case Lisp_Buffer:
                   1008:       if (!XMARKBIT (XBUFFER (obj)->name))
                   1009:        mark_buffer (obj);
                   1010:       break;
                   1011: 
                   1012:     /* Don't bother with Lisp_Buffer_Objfwd,
                   1013:        since all markable slots in current buffer marked anyway.  */
                   1014:     }
                   1015:   return original;
                   1016: }
                   1017: 
                   1018: /* Mark the pointers in a buffer structure.  */
                   1019: 
                   1020: mark_buffer (buf)
                   1021:      Lisp_Object buf;
                   1022: {
                   1023:   Lisp_Object tem;
                   1024:   register struct buffer *buffer = XBUFFER (buf);
                   1025: 
                   1026:   buffer->number = mark_object (buffer->number);
                   1027:   buffer->name = mark_object (buffer->name);
                   1028:   XMARK (buffer->name);
                   1029:   buffer->filename = mark_object (buffer->filename);
                   1030:   buffer->directory = mark_object (buffer->directory);
                   1031:   buffer->save_length = mark_object (buffer->save_length);
                   1032:   buffer->auto_save_file_name = mark_object (buffer->auto_save_file_name);
                   1033:   buffer->read_only = mark_object (buffer->read_only);
                   1034:   /* buffer->markers does not preserve from gc: scavenger removes marker from
                   1035:      the markers chain if it is freed.  See gc_sweep */
                   1036:   buffer->mark = mark_object (buffer->mark);
                   1037:   buffer->major_mode = mark_object (buffer->major_mode);
                   1038:   buffer->mode_name = mark_object (buffer->mode_name);
                   1039:   buffer->mode_line_format = mark_object (buffer->mode_line_format);
                   1040:   buffer->keymap = mark_object (buffer->keymap);
                   1041:   XSET (tem, Lisp_Vector, buffer->syntax_table_v);
                   1042:   if (buffer->syntax_table_v)
                   1043:     mark_object (tem);
                   1044:   buffer->abbrev_table = mark_object (buffer->abbrev_table);
                   1045:   buffer->case_fold_search = mark_object (buffer->case_fold_search);
                   1046:   buffer->tab_width = mark_object (buffer->tab_width);
                   1047:   buffer->fill_column = mark_object (buffer->fill_column);
                   1048:   buffer->left_margin = mark_object (buffer->left_margin);
                   1049:   buffer->auto_fill_hook = mark_object (buffer->auto_fill_hook);
                   1050:   buffer->local_var_alist = mark_object (buffer->local_var_alist);
                   1051:   buffer->truncate_lines = mark_object (buffer->truncate_lines);
                   1052:   buffer->ctl_arrow = mark_object (buffer->ctl_arrow);
                   1053:   buffer->selective_display = mark_object (buffer->selective_display);
                   1054:   buffer->minor_modes = mark_object (buffer->minor_modes);
                   1055:   buffer->overwrite_mode = mark_object (buffer->overwrite_mode);
                   1056:   buffer->abbrev_mode = mark_object (buffer->abbrev_mode);
                   1057: 
                   1058: }
                   1059: 
                   1060: /* Find all structures not marked, and free them. */
                   1061: 
                   1062: static void
                   1063: gc_sweep (old_string_block)
                   1064:      struct string_block *old_string_block;
                   1065: {
                   1066:   /* Put all unmarked conses on free list */
                   1067:   {
                   1068:     register struct cons_block *cblk;
                   1069:     register int lim = cons_block_index;
                   1070:     register int num_free = 0, num_used = 0;
                   1071: 
                   1072:     cons_free_list = 0;
                   1073:   
                   1074:     for (cblk = cons_block; cblk; cblk = cblk->next)
                   1075:       {
                   1076:        register int i;
                   1077:        for (i = 0; i < lim; i++)
                   1078:          if (!XMARKBIT (cblk->conses[i].car))
                   1079:            {
                   1080:              XSETCONS (cblk->conses[i].car, cons_free_list);
                   1081:              num_free++;
                   1082:              cons_free_list = &cblk->conses[i];
                   1083:            }
                   1084:          else num_used++;
                   1085:        lim = CONS_BLOCK_SIZE;
                   1086:       }
                   1087:     total_conses = num_used;
                   1088:     total_free_conses = num_free;
                   1089:   }
                   1090: 
                   1091:   /* Put all unmarked symbols on free list */
                   1092:   {
                   1093:     register struct symbol_block *sblk;
                   1094:     register int lim = symbol_block_index;
                   1095:     register int num_free = 0, num_used = 0;
                   1096: 
                   1097:     symbol_free_list = 0;
                   1098:   
                   1099:     for (sblk = symbol_block; sblk; sblk = sblk->next)
                   1100:       {
                   1101:        register int i;
                   1102:        for (i = 0; i < lim; i++)
                   1103:          if (!XMARKBIT (sblk->symbols[i].plist))
                   1104:            {
                   1105:              XSETSYMBOL (sblk->symbols[i].value, symbol_free_list);
                   1106:              symbol_free_list = &sblk->symbols[i];
                   1107:              num_free++;
                   1108:            }
                   1109:          else num_used++;
                   1110:        lim = SYMBOL_BLOCK_SIZE;
                   1111:       }
                   1112:     total_symbols = num_used;
                   1113:     total_free_symbols = num_free;
                   1114:   }
                   1115: 
                   1116: #ifndef standalone
                   1117:   /* Put all unmarked markers on free list.
                   1118:      Dechain each one first from the buffer it points into. */
                   1119:   {
                   1120:     register struct marker_block *mblk;
                   1121:     struct Lisp_Marker *tem1;
                   1122:     register int lim = marker_block_index;
                   1123:     register int num_free = 0, num_used = 0;
                   1124: 
                   1125:     marker_free_list = 0;
                   1126:   
                   1127:     for (mblk = marker_block; mblk; mblk = mblk->next)
                   1128:       {
                   1129:        register int i;
                   1130:        for (i = 0; i < lim; i++)
                   1131:          if (!XMARKBIT (mblk->markers[i].chain))
                   1132:            {
                   1133:              Lisp_Object tem;
                   1134:              tem1 = &mblk->markers[i];  /* tem1 avoids Sun compiler bug */
                   1135:              XSET (tem, Lisp_Marker, tem1);
                   1136:              unchain_marker (tem);
                   1137:              XSETMARKER (mblk->markers[i].chain, marker_free_list);
                   1138:              marker_free_list = &mblk->markers[i];
                   1139:              num_free++;
                   1140:            }
                   1141:          else num_used++;
                   1142:        lim = MARKER_BLOCK_SIZE;
                   1143:       }
                   1144: 
                   1145:     total_markers = num_used;
                   1146:     total_free_markers = num_free;
                   1147:   }
                   1148: 
                   1149:   /* Free all unmarked buffers */
                   1150:   {
                   1151:     register struct buffer *buffer = all_buffers, *prev = 0, *next = 0;
                   1152: 
                   1153:     while (buffer)
                   1154:       if (!XMARKBIT (buffer->name))
                   1155:        {
                   1156:          if (prev)
                   1157:            prev->next = buffer->next;
                   1158:          else
                   1159:            all_buffers = buffer->next;
                   1160:          next = buffer->next;
                   1161:          free (buffer);
                   1162:          buffer = next;
                   1163:        }
                   1164:       else
                   1165:        {
                   1166:          XUNMARK (buffer->name);
                   1167:          prev = buffer, buffer = buffer->next;
                   1168:        }
                   1169:   }
                   1170: 
                   1171: #endif standalone
                   1172: 
                   1173:   /* Free all unmarked vectors */
                   1174:   {
                   1175:     register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next = 0;
                   1176:     total_vector_size = 0;
                   1177: 
                   1178:     while (vector)
                   1179:       if (!(vector->size & most_negative_fixnum))
                   1180:        {
                   1181:          if (prev)
                   1182:            prev->next = vector->next;
                   1183:          else
                   1184:            all_vectors = vector->next;
                   1185:          next = vector->next;
                   1186:          free (vector);
                   1187:          vector = next;
                   1188:        }
                   1189:       else
                   1190:        {
                   1191:          vector->size &= ~most_negative_fixnum;
                   1192:          total_vector_size += vector->size;
                   1193:          prev = vector, vector = vector->next;
                   1194:        }
                   1195:   }
                   1196: 
                   1197:   /* Free all old string blocks, since all strings still used have been copied. */
                   1198:   {
                   1199:     register struct string_block *sblk = old_string_block;
                   1200:     while (sblk)
                   1201:       {
                   1202:        struct string_block *next = sblk->next;
                   1203:        free (sblk);
                   1204:        sblk = next;
                   1205:       }
                   1206:   }
                   1207: }
                   1208: 
                   1209: /* Initialization */
                   1210: 
                   1211: init_alloc_once ()
                   1212: {
                   1213:   register int i, x;
                   1214:   /* Compute an int in which only the sign bit is set.  */
                   1215:   for (i = 0, x = 1; (x <<= 1) & ~1; i++)
                   1216:     /*empty loop*/;
                   1217:   most_negative_fixnum = 1 << i;
                   1218:   dont_copy_flag = 1 << (i - 1);
                   1219: 
                   1220:   Vpurify_flag = Qt;
                   1221: 
                   1222:   pureptr = 0;
                   1223:   all_vectors = 0;
                   1224:   init_strings ();
                   1225:   init_cons ();
                   1226:   init_symbol ();
                   1227:   init_marker ();
                   1228:   gcprolist = 0;
                   1229:   staticidx = 0;
                   1230:   consing_since_gc = 0;
                   1231:   gc_cons_threshold = 100000;
                   1232: #ifdef VIRT_ADDR_VARIES
                   1233:   malloc_sbrk_unused = 1<<22;  /* A large number */
                   1234:   malloc_sbrk_used = 100000;   /* as reasonable as any number */
                   1235: #endif /* VIRT_ADDR_VARIES */
                   1236: }
                   1237: 
                   1238: init_alloc ()
                   1239: {
                   1240:   gcprolist = 0;
                   1241: }
                   1242: 
                   1243: void
                   1244: syms_of_alloc ()
                   1245: {
                   1246:   DefIntVar ("gc-cons-threshold", &gc_cons_threshold,
                   1247:     "*Number of bytes of consing between garbage collections.");
                   1248: 
                   1249:   DefIntVar ("pure-bytes-used", &pureptr,
                   1250:     "Number of bytes of sharable Lisp data allocated so far.");
                   1251: 
                   1252:   DefIntVar ("data-bytes-used", &malloc_sbrk_used,
                   1253:     "Number of bytes of unshared memory allocated in this session.");
                   1254: 
                   1255:   DefIntVar ("data-bytes-free", &malloc_sbrk_unused,
                   1256:     "Number of bytes of unshared memory remaining available in this session.");
                   1257: 
                   1258:   DefLispVar ("purify-flag", &Vpurify_flag,
                   1259:     "Non-nil means defun should purecopy the function definition.");
                   1260: 
                   1261:   defsubr (&Scons);
                   1262:   defsubr (&Slist);
                   1263:   defsubr (&Svector);
                   1264:   defsubr (&Smake_list);
                   1265:   defsubr (&Smake_vector);
                   1266:   defsubr (&Smake_string);
                   1267:   defsubr (&Smake_symbol);
                   1268:   defsubr (&Smake_marker);
                   1269:   defsubr (&Spurecopy);
                   1270:   defsubr (&Sgarbage_collect);
                   1271: }

unix.superglobalmegacorp.com

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