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