Mercurial > emacs
annotate src/alloc.c @ 1016:817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
assumes that minibuf_window is on the same frame as the window
configuration. Removed special case for windows whose prevs
point to themselves.
* window.c (Fset_window_configuration): Rename the argument from
ARG to CONFIGURATION, so it matches the docstring. The
make-docfile program cares.
* window.c [MULTI_FRAME] (syms_of_window): Don't staticpro
minibuf_window; the frame list will take care of it.
* window.c (window_loop): This used to keep track of the first
window processed and wait until we came back around to it. Sadly,
this doesn't work if that window gets deleted. So instead, use
Fprevious_window to find the last window to process, and loop
until we've done that one.
* window.c [not MULTI_FRAME] (init_window_once): Don't forget to
set the `mini_p' flag on the new minibuffer window to t.
* window.c (Fwindow_at): Don't check the type of the frame
argument.
* window.c [not MULTI_FRAME] (window_loop): Set frame to zero,
instead of trying to decode it.
* window.c (init_window_once): Initialize minibuf_window before
FRAME_ROOT_WINDOW, so the latter actually points to something.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Wed, 19 Aug 1992 06:40:02 +0000 |
parents | 67bfadf24043 |
children | 903883eed4de |
rev | line source |
---|---|
300 | 1 /* Storage allocation and gc for GNU Emacs Lisp interpreter. |
590 | 2 Copyright (C) 1985, 1986, 1988, 1992 Free Software Foundation, Inc. |
300 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 1, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 #include "config.h" | |
22 #include "lisp.h" | |
356 | 23 #include "puresize.h" |
300 | 24 #ifndef standalone |
25 #include "buffer.h" | |
26 #include "window.h" | |
764 | 27 #ifdef MULTI_FRAME |
28 #include "frame.h" | |
29 #endif /* MULTI_FRAME */ | |
300 | 30 #endif |
31 | |
638 | 32 #include "syssignal.h" |
33 | |
300 | 34 #define max(A,B) ((A) > (B) ? (A) : (B)) |
35 | |
36 /* Macro to verify that storage intended for Lisp objects is not | |
37 out of range to fit in the space for a pointer. | |
38 ADDRESS is the start of the block, and SIZE | |
39 is the amount of space within which objects can start. */ | |
40 #define VALIDATE_LISP_STORAGE(address, size) \ | |
41 do \ | |
42 { \ | |
43 Lisp_Object val; \ | |
44 XSET (val, Lisp_Cons, (char *) address + size); \ | |
45 if ((char *) XCONS (val) != (char *) address + size) \ | |
46 { \ | |
47 free (address); \ | |
48 memory_full (); \ | |
49 } \ | |
50 } while (0) | |
51 | |
52 /* Number of bytes of consing done since the last gc */ | |
53 int consing_since_gc; | |
54 | |
55 /* Number of bytes of consing since gc before another gc should be done. */ | |
56 int gc_cons_threshold; | |
57 | |
58 /* Nonzero during gc */ | |
59 int gc_in_progress; | |
60 | |
61 #ifndef VIRT_ADDR_VARIES | |
62 extern | |
63 #endif /* VIRT_ADDR_VARIES */ | |
64 int malloc_sbrk_used; | |
65 | |
66 #ifndef VIRT_ADDR_VARIES | |
67 extern | |
68 #endif /* VIRT_ADDR_VARIES */ | |
69 int malloc_sbrk_unused; | |
70 | |
764 | 71 /* Two limits controlling how much undo information to keep. */ |
72 int undo_limit; | |
73 int undo_strong_limit; | |
300 | 74 |
75 /* Non-nil means defun should do purecopy on the function definition */ | |
76 Lisp_Object Vpurify_flag; | |
77 | |
78 #ifndef HAVE_SHM | |
79 int pure[PURESIZE / sizeof (int)] = {0,}; /* Force it into data space! */ | |
80 #define PUREBEG (char *) pure | |
81 #else | |
82 #define pure PURE_SEG_BITS /* Use shared memory segment */ | |
83 #define PUREBEG (char *)PURE_SEG_BITS | |
356 | 84 |
85 /* This variable is used only by the XPNTR macro when HAVE_SHM is | |
86 defined. If we used the PURESIZE macro directly there, that would | |
87 make most of emacs dependent on puresize.h, which we don't want - | |
88 you should be able to change that without too much recompilation. | |
89 So map_in_data initializes pure_size, and the dependencies work | |
90 out. */ | |
91 int pure_size; | |
300 | 92 #endif /* not HAVE_SHM */ |
93 | |
94 /* Index in pure at which next pure object will be allocated. */ | |
95 int pureptr; | |
96 | |
97 /* If nonzero, this is a warning delivered by malloc and not yet displayed. */ | |
98 char *pending_malloc_warning; | |
99 | |
100 /* Maximum amount of C stack to save when a GC happens. */ | |
101 | |
102 #ifndef MAX_SAVE_STACK | |
103 #define MAX_SAVE_STACK 16000 | |
104 #endif | |
105 | |
106 /* Buffer in which we save a copy of the C stack at each GC. */ | |
107 | |
108 char *stack_copy; | |
109 int stack_copy_size; | |
110 | |
111 /* Non-zero means ignore malloc warnings. Set during initialization. */ | |
112 int ignore_warnings; | |
113 | |
114 Lisp_Object | |
115 malloc_warning_1 (str) | |
116 Lisp_Object str; | |
117 { | |
118 Fprinc (str, Vstandard_output); | |
119 write_string ("\nKilling some buffers may delay running out of memory.\n", -1); | |
120 write_string ("However, certainly by the time you receive the 95% warning,\n", -1); | |
121 write_string ("you should clean up, kill this Emacs, and start a new one.", -1); | |
122 return Qnil; | |
123 } | |
124 | |
125 /* malloc calls this if it finds we are near exhausting storage */ | |
126 malloc_warning (str) | |
127 char *str; | |
128 { | |
129 pending_malloc_warning = str; | |
130 } | |
131 | |
132 display_malloc_warning () | |
133 { | |
134 register Lisp_Object val; | |
135 | |
136 val = build_string (pending_malloc_warning); | |
137 pending_malloc_warning = 0; | |
138 internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val); | |
139 } | |
140 | |
141 /* Called if malloc returns zero */ | |
142 memory_full () | |
143 { | |
144 error ("Memory exhausted"); | |
145 } | |
146 | |
147 /* like malloc and realloc but check for no memory left */ | |
148 | |
149 long * | |
150 xmalloc (size) | |
151 int size; | |
152 { | |
153 register long *val; | |
154 | |
155 val = (long *) malloc (size); | |
156 | |
157 if (!val && size) memory_full (); | |
158 return val; | |
159 } | |
160 | |
161 long * | |
162 xrealloc (block, size) | |
163 long *block; | |
164 int size; | |
165 { | |
166 register long *val; | |
167 | |
590 | 168 /* We must call malloc explicitly when BLOCK is 0, since some |
169 reallocs don't do this. */ | |
170 if (! block) | |
171 val = (long *) malloc (size); | |
600
a8d78999e46d
*** empty log message ***
Noah Friedman <friedman@splode.com>
parents:
590
diff
changeset
|
172 else |
590 | 173 val = (long *) realloc (block, size); |
300 | 174 |
175 if (!val && size) memory_full (); | |
176 return val; | |
177 } | |
178 | |
179 #ifdef LISP_FLOAT_TYPE | |
180 /* Allocation of float cells, just like conses */ | |
181 /* We store float cells inside of float_blocks, allocating a new | |
182 float_block with malloc whenever necessary. Float cells reclaimed by | |
183 GC are put on a free list to be reallocated before allocating | |
184 any new float cells from the latest float_block. | |
185 | |
186 Each float_block is just under 1020 bytes long, | |
187 since malloc really allocates in units of powers of two | |
188 and uses 4 bytes for its own overhead. */ | |
189 | |
190 #define FLOAT_BLOCK_SIZE \ | |
191 ((1020 - sizeof (struct float_block *)) / sizeof (struct Lisp_Float)) | |
192 | |
193 struct float_block | |
194 { | |
195 struct float_block *next; | |
196 struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; | |
197 }; | |
198 | |
199 struct float_block *float_block; | |
200 int float_block_index; | |
201 | |
202 struct Lisp_Float *float_free_list; | |
203 | |
204 void | |
205 init_float () | |
206 { | |
207 float_block = (struct float_block *) malloc (sizeof (struct float_block)); | |
208 float_block->next = 0; | |
209 bzero (float_block->floats, sizeof float_block->floats); | |
210 float_block_index = 0; | |
211 float_free_list = 0; | |
212 } | |
213 | |
214 /* Explicitly free a float cell. */ | |
215 free_float (ptr) | |
216 struct Lisp_Float *ptr; | |
217 { | |
218 XFASTINT (ptr->type) = (int) float_free_list; | |
219 float_free_list = ptr; | |
220 } | |
221 | |
222 Lisp_Object | |
223 make_float (float_value) | |
224 double float_value; | |
225 { | |
226 register Lisp_Object val; | |
227 | |
228 if (float_free_list) | |
229 { | |
230 XSET (val, Lisp_Float, float_free_list); | |
231 float_free_list = (struct Lisp_Float *) XFASTINT (float_free_list->type); | |
232 } | |
233 else | |
234 { | |
235 if (float_block_index == FLOAT_BLOCK_SIZE) | |
236 { | |
237 register struct float_block *new = (struct float_block *) malloc (sizeof (struct float_block)); | |
238 if (!new) memory_full (); | |
239 VALIDATE_LISP_STORAGE (new, sizeof *new); | |
240 new->next = float_block; | |
241 float_block = new; | |
242 float_block_index = 0; | |
243 } | |
244 XSET (val, Lisp_Float, &float_block->floats[float_block_index++]); | |
245 } | |
246 XFLOAT (val)->data = float_value; | |
247 XFLOAT (val)->type = 0; /* bug chasing -wsr */ | |
248 consing_since_gc += sizeof (struct Lisp_Float); | |
249 return val; | |
250 } | |
251 | |
252 #endif /* LISP_FLOAT_TYPE */ | |
253 | |
254 /* Allocation of cons cells */ | |
255 /* We store cons cells inside of cons_blocks, allocating a new | |
256 cons_block with malloc whenever necessary. Cons cells reclaimed by | |
257 GC are put on a free list to be reallocated before allocating | |
258 any new cons cells from the latest cons_block. | |
259 | |
260 Each cons_block is just under 1020 bytes long, | |
261 since malloc really allocates in units of powers of two | |
262 and uses 4 bytes for its own overhead. */ | |
263 | |
264 #define CONS_BLOCK_SIZE \ | |
265 ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons)) | |
266 | |
267 struct cons_block | |
268 { | |
269 struct cons_block *next; | |
270 struct Lisp_Cons conses[CONS_BLOCK_SIZE]; | |
271 }; | |
272 | |
273 struct cons_block *cons_block; | |
274 int cons_block_index; | |
275 | |
276 struct Lisp_Cons *cons_free_list; | |
277 | |
278 void | |
279 init_cons () | |
280 { | |
281 cons_block = (struct cons_block *) malloc (sizeof (struct cons_block)); | |
282 cons_block->next = 0; | |
283 bzero (cons_block->conses, sizeof cons_block->conses); | |
284 cons_block_index = 0; | |
285 cons_free_list = 0; | |
286 } | |
287 | |
288 /* Explicitly free a cons cell. */ | |
289 free_cons (ptr) | |
290 struct Lisp_Cons *ptr; | |
291 { | |
292 XFASTINT (ptr->car) = (int) cons_free_list; | |
293 cons_free_list = ptr; | |
294 } | |
295 | |
296 DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |
297 "Create a new cons, give it CAR and CDR as components, and return it.") | |
298 (car, cdr) | |
299 Lisp_Object car, cdr; | |
300 { | |
301 register Lisp_Object val; | |
302 | |
303 if (cons_free_list) | |
304 { | |
305 XSET (val, Lisp_Cons, cons_free_list); | |
306 cons_free_list = (struct Lisp_Cons *) XFASTINT (cons_free_list->car); | |
307 } | |
308 else | |
309 { | |
310 if (cons_block_index == CONS_BLOCK_SIZE) | |
311 { | |
312 register struct cons_block *new = (struct cons_block *) malloc (sizeof (struct cons_block)); | |
313 if (!new) memory_full (); | |
314 VALIDATE_LISP_STORAGE (new, sizeof *new); | |
315 new->next = cons_block; | |
316 cons_block = new; | |
317 cons_block_index = 0; | |
318 } | |
319 XSET (val, Lisp_Cons, &cons_block->conses[cons_block_index++]); | |
320 } | |
321 XCONS (val)->car = car; | |
322 XCONS (val)->cdr = cdr; | |
323 consing_since_gc += sizeof (struct Lisp_Cons); | |
324 return val; | |
325 } | |
326 | |
327 DEFUN ("list", Flist, Slist, 0, MANY, 0, | |
328 "Return a newly created list with specified arguments as elements.\n\ | |
329 Any number of arguments, even zero arguments, are allowed.") | |
330 (nargs, args) | |
331 int nargs; | |
332 register Lisp_Object *args; | |
333 { | |
334 register Lisp_Object len, val, val_tail; | |
335 | |
336 XFASTINT (len) = nargs; | |
337 val = Fmake_list (len, Qnil); | |
338 val_tail = val; | |
485 | 339 while (!NILP (val_tail)) |
300 | 340 { |
341 XCONS (val_tail)->car = *args++; | |
342 val_tail = XCONS (val_tail)->cdr; | |
343 } | |
344 return val; | |
345 } | |
346 | |
347 DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |
348 "Return a newly created list of length LENGTH, with each element being INIT.") | |
349 (length, init) | |
350 register Lisp_Object length, init; | |
351 { | |
352 register Lisp_Object val; | |
353 register int size; | |
354 | |
355 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
356 length = wrong_type_argument (Qnatnump, length); | |
357 size = XINT (length); | |
358 | |
359 val = Qnil; | |
360 while (size-- > 0) | |
361 val = Fcons (init, val); | |
362 return val; | |
363 } | |
364 | |
365 /* Allocation of vectors */ | |
366 | |
367 struct Lisp_Vector *all_vectors; | |
368 | |
369 DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, | |
370 "Return a newly created vector of length LENGTH, with each element being INIT.\n\ | |
371 See also the function `vector'.") | |
372 (length, init) | |
373 register Lisp_Object length, init; | |
374 { | |
375 register int sizei, index; | |
376 register Lisp_Object vector; | |
377 register struct Lisp_Vector *p; | |
378 | |
379 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
380 length = wrong_type_argument (Qnatnump, length); | |
381 sizei = XINT (length); | |
382 | |
383 p = (struct Lisp_Vector *) malloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)); | |
384 if (p == 0) | |
385 memory_full (); | |
386 VALIDATE_LISP_STORAGE (p, 0); | |
387 | |
388 XSET (vector, Lisp_Vector, p); | |
389 consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object); | |
390 | |
391 p->size = sizei; | |
392 p->next = all_vectors; | |
393 all_vectors = p; | |
394 | |
395 for (index = 0; index < sizei; index++) | |
396 p->contents[index] = init; | |
397 | |
398 return vector; | |
399 } | |
400 | |
401 DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | |
402 "Return a newly created vector with specified arguments as elements.\n\ | |
403 Any number of arguments, even zero arguments, are allowed.") | |
404 (nargs, args) | |
405 register int nargs; | |
406 Lisp_Object *args; | |
407 { | |
408 register Lisp_Object len, val; | |
409 register int index; | |
410 register struct Lisp_Vector *p; | |
411 | |
412 XFASTINT (len) = nargs; | |
413 val = Fmake_vector (len, Qnil); | |
414 p = XVECTOR (val); | |
415 for (index = 0; index < nargs; index++) | |
416 p->contents[index] = args[index]; | |
417 return val; | |
418 } | |
419 | |
420 DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | |
421 "Create a byte-code object with specified arguments as elements.\n\ | |
422 The arguments should be the arglist, bytecode-string, constant vector,\n\ | |
423 stack size, (optional) doc string, and (optional) interactive spec.\n\ | |
424 The first four arguments are required; at most six have any\n\ | |
425 significance.") | |
426 (nargs, args) | |
427 register int nargs; | |
428 Lisp_Object *args; | |
429 { | |
430 register Lisp_Object len, val; | |
431 register int index; | |
432 register struct Lisp_Vector *p; | |
433 | |
434 XFASTINT (len) = nargs; | |
485 | 435 if (!NILP (Vpurify_flag)) |
300 | 436 val = make_pure_vector (len); |
437 else | |
438 val = Fmake_vector (len, Qnil); | |
439 p = XVECTOR (val); | |
440 for (index = 0; index < nargs; index++) | |
441 { | |
485 | 442 if (!NILP (Vpurify_flag)) |
300 | 443 args[index] = Fpurecopy (args[index]); |
444 p->contents[index] = args[index]; | |
445 } | |
446 XSETTYPE (val, Lisp_Compiled); | |
447 return val; | |
448 } | |
449 | |
450 /* Allocation of symbols. | |
451 Just like allocation of conses! | |
452 | |
453 Each symbol_block is just under 1020 bytes long, | |
454 since malloc really allocates in units of powers of two | |
455 and uses 4 bytes for its own overhead. */ | |
456 | |
457 #define SYMBOL_BLOCK_SIZE \ | |
458 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) | |
459 | |
460 struct symbol_block | |
461 { | |
462 struct symbol_block *next; | |
463 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; | |
464 }; | |
465 | |
466 struct symbol_block *symbol_block; | |
467 int symbol_block_index; | |
468 | |
469 struct Lisp_Symbol *symbol_free_list; | |
470 | |
471 void | |
472 init_symbol () | |
473 { | |
474 symbol_block = (struct symbol_block *) malloc (sizeof (struct symbol_block)); | |
475 symbol_block->next = 0; | |
476 bzero (symbol_block->symbols, sizeof symbol_block->symbols); | |
477 symbol_block_index = 0; | |
478 symbol_free_list = 0; | |
479 } | |
480 | |
481 DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | |
482 "Return a newly allocated uninterned symbol whose name is NAME.\n\ | |
483 Its value and function definition are void, and its property list is nil.") | |
484 (str) | |
485 Lisp_Object str; | |
486 { | |
487 register Lisp_Object val; | |
488 register struct Lisp_Symbol *p; | |
489 | |
490 CHECK_STRING (str, 0); | |
491 | |
492 if (symbol_free_list) | |
493 { | |
494 XSET (val, Lisp_Symbol, symbol_free_list); | |
495 symbol_free_list | |
496 = (struct Lisp_Symbol *) XFASTINT (symbol_free_list->value); | |
497 } | |
498 else | |
499 { | |
500 if (symbol_block_index == SYMBOL_BLOCK_SIZE) | |
501 { | |
502 struct symbol_block *new = (struct symbol_block *) malloc (sizeof (struct symbol_block)); | |
503 if (!new) memory_full (); | |
504 VALIDATE_LISP_STORAGE (new, sizeof *new); | |
505 new->next = symbol_block; | |
506 symbol_block = new; | |
507 symbol_block_index = 0; | |
508 } | |
509 XSET (val, Lisp_Symbol, &symbol_block->symbols[symbol_block_index++]); | |
510 } | |
511 p = XSYMBOL (val); | |
512 p->name = XSTRING (str); | |
513 p->plist = Qnil; | |
514 p->value = Qunbound; | |
515 p->function = Qunbound; | |
516 p->next = 0; | |
517 consing_since_gc += sizeof (struct Lisp_Symbol); | |
518 return val; | |
519 } | |
520 | |
521 /* Allocation of markers. | |
522 Works like allocation of conses. */ | |
523 | |
524 #define MARKER_BLOCK_SIZE \ | |
525 ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker)) | |
526 | |
527 struct marker_block | |
528 { | |
529 struct marker_block *next; | |
530 struct Lisp_Marker markers[MARKER_BLOCK_SIZE]; | |
531 }; | |
532 | |
533 struct marker_block *marker_block; | |
534 int marker_block_index; | |
535 | |
536 struct Lisp_Marker *marker_free_list; | |
537 | |
538 void | |
539 init_marker () | |
540 { | |
541 marker_block = (struct marker_block *) malloc (sizeof (struct marker_block)); | |
542 marker_block->next = 0; | |
543 bzero (marker_block->markers, sizeof marker_block->markers); | |
544 marker_block_index = 0; | |
545 marker_free_list = 0; | |
546 } | |
547 | |
548 DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |
549 "Return a newly allocated marker which does not point at any place.") | |
550 () | |
551 { | |
552 register Lisp_Object val; | |
553 register struct Lisp_Marker *p; | |
638 | 554 |
300 | 555 if (marker_free_list) |
556 { | |
557 XSET (val, Lisp_Marker, marker_free_list); | |
558 marker_free_list | |
559 = (struct Lisp_Marker *) XFASTINT (marker_free_list->chain); | |
560 } | |
561 else | |
562 { | |
563 if (marker_block_index == MARKER_BLOCK_SIZE) | |
564 { | |
565 struct marker_block *new = (struct marker_block *) malloc (sizeof (struct marker_block)); | |
566 if (!new) memory_full (); | |
567 VALIDATE_LISP_STORAGE (new, sizeof *new); | |
568 new->next = marker_block; | |
569 marker_block = new; | |
570 marker_block_index = 0; | |
571 } | |
572 XSET (val, Lisp_Marker, &marker_block->markers[marker_block_index++]); | |
573 } | |
574 p = XMARKER (val); | |
575 p->buffer = 0; | |
576 p->bufpos = 0; | |
577 p->chain = Qnil; | |
578 consing_since_gc += sizeof (struct Lisp_Marker); | |
579 return val; | |
580 } | |
581 | |
582 /* Allocation of strings */ | |
583 | |
584 /* Strings reside inside of string_blocks. The entire data of the string, | |
585 both the size and the contents, live in part of the `chars' component of a string_block. | |
586 The `pos' component is the index within `chars' of the first free byte. | |
587 | |
588 first_string_block points to the first string_block ever allocated. | |
589 Each block points to the next one with its `next' field. | |
590 The `prev' fields chain in reverse order. | |
591 The last one allocated is the one currently being filled. | |
592 current_string_block points to it. | |
593 | |
594 The string_blocks that hold individual large strings | |
595 go in a separate chain, started by large_string_blocks. */ | |
596 | |
597 | |
598 /* String blocks contain this many useful bytes. | |
599 8188 is power of 2, minus 4 for malloc overhead. */ | |
600 #define STRING_BLOCK_SIZE (8188 - sizeof (struct string_block_head)) | |
601 | |
602 /* A string bigger than this gets its own specially-made string block | |
603 if it doesn't fit in the current one. */ | |
604 #define STRING_BLOCK_OUTSIZE 1024 | |
605 | |
606 struct string_block_head | |
607 { | |
608 struct string_block *next, *prev; | |
609 int pos; | |
610 }; | |
611 | |
612 struct string_block | |
613 { | |
614 struct string_block *next, *prev; | |
615 int pos; | |
616 char chars[STRING_BLOCK_SIZE]; | |
617 }; | |
618 | |
619 /* This points to the string block we are now allocating strings. */ | |
620 | |
621 struct string_block *current_string_block; | |
622 | |
623 /* This points to the oldest string block, the one that starts the chain. */ | |
624 | |
625 struct string_block *first_string_block; | |
626 | |
627 /* Last string block in chain of those made for individual large strings. */ | |
628 | |
629 struct string_block *large_string_blocks; | |
630 | |
631 /* If SIZE is the length of a string, this returns how many bytes | |
632 the string occupies in a string_block (including padding). */ | |
633 | |
634 #define STRING_FULLSIZE(size) (((size) + sizeof (struct Lisp_String) + PAD) \ | |
635 & ~(PAD - 1)) | |
636 #define PAD (sizeof (int)) | |
637 | |
638 #if 0 | |
639 #define STRING_FULLSIZE(SIZE) \ | |
640 (((SIZE) + 2 * sizeof (int)) & ~(sizeof (int) - 1)) | |
641 #endif | |
642 | |
643 void | |
644 init_strings () | |
645 { | |
646 current_string_block = (struct string_block *) malloc (sizeof (struct string_block)); | |
647 first_string_block = current_string_block; | |
648 consing_since_gc += sizeof (struct string_block); | |
649 current_string_block->next = 0; | |
650 current_string_block->prev = 0; | |
651 current_string_block->pos = 0; | |
652 large_string_blocks = 0; | |
653 } | |
654 | |
655 DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, | |
656 "Return a newly created string of length LENGTH, with each element being INIT.\n\ | |
657 Both LENGTH and INIT must be numbers.") | |
658 (length, init) | |
659 Lisp_Object length, init; | |
660 { | |
661 register Lisp_Object val; | |
662 register unsigned char *p, *end, c; | |
663 | |
664 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
665 length = wrong_type_argument (Qnatnump, length); | |
666 CHECK_NUMBER (init, 1); | |
667 val = make_uninit_string (XINT (length)); | |
668 c = XINT (init); | |
669 p = XSTRING (val)->data; | |
670 end = p + XSTRING (val)->size; | |
671 while (p != end) | |
672 *p++ = c; | |
673 *p = 0; | |
674 return val; | |
675 } | |
676 | |
677 Lisp_Object | |
678 make_string (contents, length) | |
679 char *contents; | |
680 int length; | |
681 { | |
682 register Lisp_Object val; | |
683 val = make_uninit_string (length); | |
684 bcopy (contents, XSTRING (val)->data, length); | |
685 return val; | |
686 } | |
687 | |
688 Lisp_Object | |
689 build_string (str) | |
690 char *str; | |
691 { | |
692 return make_string (str, strlen (str)); | |
693 } | |
694 | |
695 Lisp_Object | |
696 make_uninit_string (length) | |
697 int length; | |
698 { | |
699 register Lisp_Object val; | |
700 register int fullsize = STRING_FULLSIZE (length); | |
701 | |
702 if (length < 0) abort (); | |
703 | |
704 if (fullsize <= STRING_BLOCK_SIZE - current_string_block->pos) | |
705 /* This string can fit in the current string block */ | |
706 { | |
707 XSET (val, Lisp_String, | |
708 (struct Lisp_String *) (current_string_block->chars + current_string_block->pos)); | |
709 current_string_block->pos += fullsize; | |
710 } | |
711 else if (fullsize > STRING_BLOCK_OUTSIZE) | |
712 /* This string gets its own string block */ | |
713 { | |
714 register struct string_block *new | |
715 = (struct string_block *) malloc (sizeof (struct string_block_head) + fullsize); | |
716 VALIDATE_LISP_STORAGE (new, 0); | |
717 if (!new) memory_full (); | |
718 consing_since_gc += sizeof (struct string_block_head) + fullsize; | |
719 new->pos = fullsize; | |
720 new->next = large_string_blocks; | |
721 large_string_blocks = new; | |
722 XSET (val, Lisp_String, | |
723 (struct Lisp_String *) ((struct string_block_head *)new + 1)); | |
724 } | |
725 else | |
726 /* Make a new current string block and start it off with this string */ | |
727 { | |
728 register struct string_block *new | |
729 = (struct string_block *) malloc (sizeof (struct string_block)); | |
730 if (!new) memory_full (); | |
731 VALIDATE_LISP_STORAGE (new, sizeof *new); | |
732 consing_since_gc += sizeof (struct string_block); | |
733 current_string_block->next = new; | |
734 new->prev = current_string_block; | |
735 new->next = 0; | |
736 current_string_block = new; | |
737 new->pos = fullsize; | |
738 XSET (val, Lisp_String, | |
739 (struct Lisp_String *) current_string_block->chars); | |
740 } | |
741 | |
742 XSTRING (val)->size = length; | |
743 XSTRING (val)->data[length] = 0; | |
744 | |
745 return val; | |
746 } | |
747 | |
748 /* Return a newly created vector or string with specified arguments as | |
749 elements. If all the arguments are characters, make a string; | |
750 otherwise, make a vector. Any number of arguments, even zero | |
751 arguments, are allowed. */ | |
752 | |
753 Lisp_Object | |
434 | 754 make_array (nargs, args) |
300 | 755 register int nargs; |
756 Lisp_Object *args; | |
757 { | |
758 int i; | |
759 | |
760 for (i = 0; i < nargs; i++) | |
761 if (XTYPE (args[i]) != Lisp_Int | |
762 || (unsigned) XINT (args[i]) >= 0400) | |
763 return Fvector (nargs, args); | |
764 | |
765 /* Since the loop exited, we know that all the things in it are | |
766 characters, so we can make a string. */ | |
767 { | |
768 Lisp_Object result = Fmake_string (nargs, make_number (0)); | |
769 | |
770 for (i = 0; i < nargs; i++) | |
771 XSTRING (result)->data[i] = XINT (args[i]); | |
772 | |
773 return result; | |
774 } | |
775 } | |
776 | |
777 /* Note: the user cannot manipulate ropes portably by referring | |
778 to the chars of the string, because combining two chars to make a GLYPH | |
779 depends on endianness. */ | |
780 | |
781 DEFUN ("make-rope", Fmake_rope, Smake_rope, 0, MANY, 0, | |
363 | 782 "Return a newly created rope containing the arguments of this function.\n\ |
300 | 783 A rope is a string, except that its contents will be treated as an\n\ |
784 array of glyphs, where a glyph is an integer type that may be larger\n\ | |
785 than a character. Emacs is normally configured to use 8-bit glyphs,\n\ | |
786 so ropes are normally no different from strings. But Emacs may be\n\ | |
787 configured to use 16-bit glyphs, to allow the use of larger fonts.\n\ | |
788 \n\ | |
789 Each argument (which must be an integer) specifies one glyph, whatever\n\ | |
790 size glyphs may be.\n\ | |
791 \n\ | |
792 See variable `buffer-display-table' for the uses of ropes.") | |
793 (nargs, args) | |
794 register int nargs; | |
795 Lisp_Object *args; | |
796 { | |
797 register int i; | |
798 register Lisp_Object val; | |
799 register GLYPH *p; | |
800 | |
801 val = make_uninit_string (nargs * sizeof (GLYPH)); | |
802 | |
803 p = (GLYPH *) XSTRING (val)->data; | |
804 for (i = 0; i < nargs; i++) | |
805 { | |
806 CHECK_NUMBER (args[i], i); | |
807 p[i] = XFASTINT (args[i]); | |
808 } | |
809 return val; | |
810 } | |
811 | |
812 DEFUN ("rope-elt", Frope_elt, Srope_elt, 2, 2, 0, | |
813 "Return an element of rope R at index N.\n\ | |
814 A rope is a string in which each pair of bytes is considered an element.\n\ | |
815 See variable `buffer-display-table' for the uses of ropes.") | |
816 (r, n) | |
817 { | |
818 CHECK_STRING (r, 0); | |
819 CHECK_NUMBER (n, 1); | |
820 if ((XSTRING (r)->size / sizeof (GLYPH)) <= XINT (n) || XINT (n) < 0) | |
821 args_out_of_range (r, n); | |
822 return ((GLYPH *) XSTRING (r)->data)[XFASTINT (n)]; | |
823 } | |
824 | |
825 /* Must get an error if pure storage is full, | |
826 since if it cannot hold a large string | |
827 it may be able to hold conses that point to that string; | |
828 then the string is not protected from gc. */ | |
829 | |
830 Lisp_Object | |
831 make_pure_string (data, length) | |
832 char *data; | |
833 int length; | |
834 { | |
835 register Lisp_Object new; | |
836 register int size = sizeof (int) + length + 1; | |
837 | |
838 if (pureptr + size > PURESIZE) | |
839 error ("Pure Lisp storage exhausted"); | |
840 XSET (new, Lisp_String, PUREBEG + pureptr); | |
841 XSTRING (new)->size = length; | |
842 bcopy (data, XSTRING (new)->data, length); | |
843 XSTRING (new)->data[length] = 0; | |
844 pureptr += (size + sizeof (int) - 1) | |
845 / sizeof (int) * sizeof (int); | |
846 return new; | |
847 } | |
848 | |
849 Lisp_Object | |
850 pure_cons (car, cdr) | |
851 Lisp_Object car, cdr; | |
852 { | |
853 register Lisp_Object new; | |
854 | |
855 if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE) | |
856 error ("Pure Lisp storage exhausted"); | |
857 XSET (new, Lisp_Cons, PUREBEG + pureptr); | |
858 pureptr += sizeof (struct Lisp_Cons); | |
859 XCONS (new)->car = Fpurecopy (car); | |
860 XCONS (new)->cdr = Fpurecopy (cdr); | |
861 return new; | |
862 } | |
863 | |
864 #ifdef LISP_FLOAT_TYPE | |
865 | |
866 Lisp_Object | |
867 make_pure_float (num) | |
868 double num; | |
869 { | |
870 register Lisp_Object new; | |
871 | |
872 if (pureptr + sizeof (struct Lisp_Float) > PURESIZE) | |
873 error ("Pure Lisp storage exhausted"); | |
874 XSET (new, Lisp_Float, PUREBEG + pureptr); | |
875 pureptr += sizeof (struct Lisp_Float); | |
876 XFLOAT (new)->data = num; | |
877 XFLOAT (new)->type = 0; /* bug chasing -wsr */ | |
878 return new; | |
879 } | |
880 | |
881 #endif /* LISP_FLOAT_TYPE */ | |
882 | |
883 Lisp_Object | |
884 make_pure_vector (len) | |
885 int len; | |
886 { | |
887 register Lisp_Object new; | |
888 register int size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object); | |
889 | |
890 if (pureptr + size > PURESIZE) | |
891 error ("Pure Lisp storage exhausted"); | |
892 | |
893 XSET (new, Lisp_Vector, PUREBEG + pureptr); | |
894 pureptr += size; | |
895 XVECTOR (new)->size = len; | |
896 return new; | |
897 } | |
898 | |
899 DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, | |
900 "Make a copy of OBJECT in pure storage.\n\ | |
901 Recursively copies contents of vectors and cons cells.\n\ | |
902 Does not copy symbols.") | |
903 (obj) | |
904 register Lisp_Object obj; | |
905 { | |
906 register Lisp_Object new, tem; | |
907 register int i; | |
908 | |
485 | 909 if (NILP (Vpurify_flag)) |
300 | 910 return obj; |
911 | |
912 if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) | |
913 && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) | |
914 return obj; | |
915 | |
916 #ifdef SWITCH_ENUM_BUG | |
917 switch ((int) XTYPE (obj)) | |
918 #else | |
919 switch (XTYPE (obj)) | |
920 #endif | |
921 { | |
922 case Lisp_Marker: | |
923 error ("Attempt to copy a marker to pure storage"); | |
924 | |
925 case Lisp_Cons: | |
926 return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr); | |
927 | |
928 #ifdef LISP_FLOAT_TYPE | |
929 case Lisp_Float: | |
930 return make_pure_float (XFLOAT (obj)->data); | |
931 #endif /* LISP_FLOAT_TYPE */ | |
932 | |
933 case Lisp_String: | |
934 return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size); | |
935 | |
936 case Lisp_Compiled: | |
937 case Lisp_Vector: | |
938 new = make_pure_vector (XVECTOR (obj)->size); | |
939 for (i = 0; i < XVECTOR (obj)->size; i++) | |
940 { | |
941 tem = XVECTOR (obj)->contents[i]; | |
942 XVECTOR (new)->contents[i] = Fpurecopy (tem); | |
943 } | |
944 XSETTYPE (new, XTYPE (obj)); | |
945 return new; | |
946 | |
947 default: | |
948 return obj; | |
949 } | |
950 } | |
951 | |
952 /* Recording what needs to be marked for gc. */ | |
953 | |
954 struct gcpro *gcprolist; | |
955 | |
727 | 956 #define NSTATICS 512 |
300 | 957 |
958 Lisp_Object *staticvec[NSTATICS] = {0}; | |
959 | |
960 int staticidx = 0; | |
961 | |
962 /* Put an entry in staticvec, pointing at the variable whose address is given */ | |
963 | |
964 void | |
965 staticpro (varaddress) | |
966 Lisp_Object *varaddress; | |
967 { | |
968 staticvec[staticidx++] = varaddress; | |
969 if (staticidx >= NSTATICS) | |
970 abort (); | |
971 } | |
972 | |
973 struct catchtag | |
974 { | |
975 Lisp_Object tag; | |
976 Lisp_Object val; | |
977 struct catchtag *next; | |
978 /* jmp_buf jmp; /* We don't need this for GC purposes */ | |
979 }; | |
980 | |
981 struct backtrace | |
982 { | |
983 struct backtrace *next; | |
984 Lisp_Object *function; | |
985 Lisp_Object *args; /* Points to vector of args. */ | |
986 int nargs; /* length of vector */ | |
987 /* if nargs is UNEVALLED, args points to slot holding list of unevalled args */ | |
988 char evalargs; | |
989 }; | |
990 | |
991 /* Two flags that are set during GC in the `size' component | |
992 of a string or vector. On some machines, these flags | |
993 are defined by the m- file to be different bits. */ | |
994 | |
995 /* On vector, means it has been marked. | |
996 On string size field or a reference to a string, | |
997 means not the last reference in the chain. */ | |
998 | |
999 #ifndef ARRAY_MARK_FLAG | |
1000 #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT) | |
1001 #endif /* no ARRAY_MARK_FLAG */ | |
1002 | |
1003 /* Any slot that is a Lisp_Object can point to a string | |
1004 and thus can be put on a string's reference-chain | |
1005 and thus may need to have its ARRAY_MARK_FLAG set. | |
1006 This includes the slots whose markbits are used to mark | |
1007 the containing objects. */ | |
1008 | |
1009 #if ARRAY_MARK_FLAG == MARKBIT | |
1010 you lose | |
1011 #endif | |
1012 | |
1013 int total_conses, total_markers, total_symbols, total_string_size, total_vector_size; | |
1014 int total_free_conses, total_free_markers, total_free_symbols; | |
1015 #ifdef LISP_FLOAT_TYPE | |
1016 int total_free_floats, total_floats; | |
1017 #endif /* LISP_FLOAT_TYPE */ | |
1018 | |
1019 static void mark_object (), mark_buffer (); | |
1020 static void clear_marks (), gc_sweep (); | |
1021 static void compact_strings (); | |
1022 | |
1023 DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", | |
1024 "Reclaim storage for Lisp objects no longer needed.\n\ | |
1025 Returns info on amount of space in use:\n\ | |
1026 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\ | |
1027 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS\n\ | |
1028 (USED-FLOATS . FREE-FLOATS))\n\ | |
1029 Garbage collection happens automatically if you cons more than\n\ | |
1030 `gc-cons-threshold' bytes of Lisp data since previous garbage collection.") | |
1031 () | |
1032 { | |
1033 register struct gcpro *tail; | |
1034 register struct specbinding *bind; | |
1035 struct catchtag *catch; | |
1036 struct handler *handler; | |
1037 register struct backtrace *backlist; | |
1038 register Lisp_Object tem; | |
1039 char *omessage = echo_area_glyphs; | |
1040 char stack_top_variable; | |
1041 register int i; | |
1042 | |
1043 /* Save a copy of the contents of the stack, for debugging. */ | |
1044 #if MAX_SAVE_STACK > 0 | |
485 | 1045 if (NILP (Vpurify_flag)) |
300 | 1046 { |
1047 i = &stack_top_variable - stack_bottom; | |
1048 if (i < 0) i = -i; | |
1049 if (i < MAX_SAVE_STACK) | |
1050 { | |
1051 if (stack_copy == 0) | |
1052 stack_copy = (char *) malloc (stack_copy_size = i); | |
1053 else if (stack_copy_size < i) | |
1054 stack_copy = (char *) realloc (stack_copy, (stack_copy_size = i)); | |
1055 if (stack_copy) | |
1056 { | |
1057 if ((int) (&stack_top_variable - stack_bottom) > 0) | |
1058 bcopy (stack_bottom, stack_copy, i); | |
1059 else | |
1060 bcopy (&stack_top_variable, stack_copy, i); | |
1061 } | |
1062 } | |
1063 } | |
1064 #endif /* MAX_SAVE_STACK > 0 */ | |
1065 | |
1066 if (!noninteractive) | |
1067 message1 ("Garbage collecting..."); | |
1068 | |
1069 /* Don't keep command history around forever */ | |
1070 tem = Fnthcdr (make_number (30), Vcommand_history); | |
1071 if (CONSP (tem)) | |
1072 XCONS (tem)->cdr = Qnil; | |
648 | 1073 |
300 | 1074 /* Likewise for undo information. */ |
1075 { | |
1076 register struct buffer *nextb = all_buffers; | |
1077 | |
1078 while (nextb) | |
1079 { | |
648 | 1080 /* If a buffer's undo list is Qt, that means that undo is |
1081 turned off in that buffer. Calling truncate_undo_list on | |
1082 Qt tends to return NULL, which effectively turns undo back on. | |
1083 So don't call truncate_undo_list if undo_list is Qt. */ | |
1084 if (! EQ (nextb->undo_list, Qt)) | |
1085 nextb->undo_list | |
764 | 1086 = truncate_undo_list (nextb->undo_list, undo_limit, |
1087 undo_strong_limit); | |
300 | 1088 nextb = nextb->next; |
1089 } | |
1090 } | |
1091 | |
1092 gc_in_progress = 1; | |
1093 | |
1094 /* clear_marks (); */ | |
1095 | |
1096 /* In each "large string", set the MARKBIT of the size field. | |
1097 That enables mark_object to recognize them. */ | |
1098 { | |
1099 register struct string_block *b; | |
1100 for (b = large_string_blocks; b; b = b->next) | |
1101 ((struct Lisp_String *)(&b->chars[0]))->size |= MARKBIT; | |
1102 } | |
1103 | |
1104 /* Mark all the special slots that serve as the roots of accessibility. | |
1105 | |
1106 Usually the special slots to mark are contained in particular structures. | |
1107 Then we know no slot is marked twice because the structures don't overlap. | |
1108 In some cases, the structures point to the slots to be marked. | |
1109 For these, we use MARKBIT to avoid double marking of the slot. */ | |
1110 | |
1111 for (i = 0; i < staticidx; i++) | |
1112 mark_object (staticvec[i]); | |
1113 for (tail = gcprolist; tail; tail = tail->next) | |
1114 for (i = 0; i < tail->nvars; i++) | |
1115 if (!XMARKBIT (tail->var[i])) | |
1116 { | |
1117 mark_object (&tail->var[i]); | |
1118 XMARK (tail->var[i]); | |
1119 } | |
1120 for (bind = specpdl; bind != specpdl_ptr; bind++) | |
1121 { | |
1122 mark_object (&bind->symbol); | |
1123 mark_object (&bind->old_value); | |
1124 } | |
1125 for (catch = catchlist; catch; catch = catch->next) | |
1126 { | |
1127 mark_object (&catch->tag); | |
1128 mark_object (&catch->val); | |
1129 } | |
1130 for (handler = handlerlist; handler; handler = handler->next) | |
1131 { | |
1132 mark_object (&handler->handler); | |
1133 mark_object (&handler->var); | |
1134 } | |
1135 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
1136 { | |
1137 if (!XMARKBIT (*backlist->function)) | |
1138 { | |
1139 mark_object (backlist->function); | |
1140 XMARK (*backlist->function); | |
1141 } | |
1142 if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | |
1143 i = 0; | |
1144 else | |
1145 i = backlist->nargs - 1; | |
1146 for (; i >= 0; i--) | |
1147 if (!XMARKBIT (backlist->args[i])) | |
1148 { | |
1149 mark_object (&backlist->args[i]); | |
1150 XMARK (backlist->args[i]); | |
1151 } | |
1152 } | |
1153 | |
1154 gc_sweep (); | |
1155 | |
1156 /* Clear the mark bits that we set in certain root slots. */ | |
1157 | |
1158 for (tail = gcprolist; tail; tail = tail->next) | |
1159 for (i = 0; i < tail->nvars; i++) | |
1160 XUNMARK (tail->var[i]); | |
1161 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
1162 { | |
1163 XUNMARK (*backlist->function); | |
1164 if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | |
1165 i = 0; | |
1166 else | |
1167 i = backlist->nargs - 1; | |
1168 for (; i >= 0; i--) | |
1169 XUNMARK (backlist->args[i]); | |
1170 } | |
1171 XUNMARK (buffer_defaults.name); | |
1172 XUNMARK (buffer_local_symbols.name); | |
1173 | |
1174 /* clear_marks (); */ | |
1175 gc_in_progress = 0; | |
1176 | |
1177 consing_since_gc = 0; | |
1178 if (gc_cons_threshold < 10000) | |
1179 gc_cons_threshold = 10000; | |
1180 | |
1181 if (omessage) | |
1182 message1 (omessage); | |
1183 else if (!noninteractive) | |
1184 message1 ("Garbage collecting...done"); | |
1185 | |
1186 return Fcons (Fcons (make_number (total_conses), | |
1187 make_number (total_free_conses)), | |
1188 Fcons (Fcons (make_number (total_symbols), | |
1189 make_number (total_free_symbols)), | |
1190 Fcons (Fcons (make_number (total_markers), | |
1191 make_number (total_free_markers)), | |
1192 Fcons (make_number (total_string_size), | |
1193 Fcons (make_number (total_vector_size), | |
1194 | |
1195 #ifdef LISP_FLOAT_TYPE | |
1196 Fcons (Fcons (make_number (total_floats), | |
1197 make_number (total_free_floats)), | |
1198 Qnil) | |
1199 #else /* not LISP_FLOAT_TYPE */ | |
1200 Qnil | |
1201 #endif /* not LISP_FLOAT_TYPE */ | |
1202 ))))); | |
1203 } | |
1204 | |
1205 #if 0 | |
1206 static void | |
1207 clear_marks () | |
1208 { | |
1209 /* Clear marks on all conses */ | |
1210 { | |
1211 register struct cons_block *cblk; | |
1212 register int lim = cons_block_index; | |
1213 | |
1214 for (cblk = cons_block; cblk; cblk = cblk->next) | |
1215 { | |
1216 register int i; | |
1217 for (i = 0; i < lim; i++) | |
1218 XUNMARK (cblk->conses[i].car); | |
1219 lim = CONS_BLOCK_SIZE; | |
1220 } | |
1221 } | |
1222 /* Clear marks on all symbols */ | |
1223 { | |
1224 register struct symbol_block *sblk; | |
1225 register int lim = symbol_block_index; | |
1226 | |
1227 for (sblk = symbol_block; sblk; sblk = sblk->next) | |
1228 { | |
1229 register int i; | |
1230 for (i = 0; i < lim; i++) | |
1231 { | |
1232 XUNMARK (sblk->symbols[i].plist); | |
1233 } | |
1234 lim = SYMBOL_BLOCK_SIZE; | |
1235 } | |
1236 } | |
1237 /* Clear marks on all markers */ | |
1238 { | |
1239 register struct marker_block *sblk; | |
1240 register int lim = marker_block_index; | |
1241 | |
1242 for (sblk = marker_block; sblk; sblk = sblk->next) | |
1243 { | |
1244 register int i; | |
1245 for (i = 0; i < lim; i++) | |
1246 XUNMARK (sblk->markers[i].chain); | |
1247 lim = MARKER_BLOCK_SIZE; | |
1248 } | |
1249 } | |
1250 /* Clear mark bits on all buffers */ | |
1251 { | |
1252 register struct buffer *nextb = all_buffers; | |
1253 | |
1254 while (nextb) | |
1255 { | |
1256 XUNMARK (nextb->name); | |
1257 nextb = nextb->next; | |
1258 } | |
1259 } | |
1260 } | |
1261 #endif | |
1262 | |
1263 /* Mark reference to a Lisp_Object. If the object referred to | |
1264 has not been seen yet, recursively mark all the references contained in it. | |
1265 | |
1266 If the object referenced is a short string, the referrencing slot | |
1267 is threaded into a chain of such slots, pointed to from | |
1268 the `size' field of the string. The actual string size | |
1269 lives in the last slot in the chain. We recognize the end | |
1270 because it is < (unsigned) STRING_BLOCK_SIZE. */ | |
1271 | |
1272 static void | |
1273 mark_object (objptr) | |
1274 Lisp_Object *objptr; | |
1275 { | |
1276 register Lisp_Object obj; | |
1277 | |
1278 obj = *objptr; | |
1279 XUNMARK (obj); | |
1280 | |
1281 loop: | |
1282 | |
1283 if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) | |
1284 && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) | |
1285 return; | |
1286 | |
1287 #ifdef SWITCH_ENUM_BUG | |
1288 switch ((int) XGCTYPE (obj)) | |
1289 #else | |
1290 switch (XGCTYPE (obj)) | |
1291 #endif | |
1292 { | |
1293 case Lisp_String: | |
1294 { | |
1295 register struct Lisp_String *ptr = XSTRING (obj); | |
1296 | |
1297 if (ptr->size & MARKBIT) | |
1298 /* A large string. Just set ARRAY_MARK_FLAG. */ | |
1299 ptr->size |= ARRAY_MARK_FLAG; | |
1300 else | |
1301 { | |
1302 /* A small string. Put this reference | |
1303 into the chain of references to it. | |
1304 The address OBJPTR is even, so if the address | |
1305 includes MARKBIT, put it in the low bit | |
1306 when we store OBJPTR into the size field. */ | |
1307 | |
1308 if (XMARKBIT (*objptr)) | |
1309 { | |
1310 XFASTINT (*objptr) = ptr->size; | |
1311 XMARK (*objptr); | |
1312 } | |
1313 else | |
1314 XFASTINT (*objptr) = ptr->size; | |
1315 if ((int)objptr & 1) abort (); | |
1316 ptr->size = (int) objptr & ~MARKBIT; | |
1317 if ((int) objptr & MARKBIT) | |
1318 ptr->size ++; | |
1319 } | |
1320 } | |
1321 break; | |
1322 | |
1323 case Lisp_Vector: | |
1324 case Lisp_Window: | |
1325 case Lisp_Process: | |
1326 case Lisp_Window_Configuration: | |
1327 case Lisp_Compiled: | |
1328 { | |
1329 register struct Lisp_Vector *ptr = XVECTOR (obj); | |
1330 register int size = ptr->size; | |
1331 register int i; | |
1332 | |
1333 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | |
1334 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | |
1335 for (i = 0; i < size; i++) /* and then mark its elements */ | |
1336 mark_object (&ptr->contents[i]); | |
1337 } | |
1338 break; | |
1339 | |
764 | 1340 #ifdef MULTI_FRAME |
1341 case Lisp_Frame: | |
300 | 1342 { |
764 | 1343 register struct frame *ptr = XFRAME (obj); |
300 | 1344 register int size = ptr->size; |
1345 register int i; | |
1346 | |
1347 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | |
1348 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | |
1349 | |
1350 mark_object (&ptr->name); | |
764 | 1351 mark_object (&ptr->focus_frame); |
300 | 1352 mark_object (&ptr->width); |
1353 mark_object (&ptr->height); | |
1354 mark_object (&ptr->selected_window); | |
1355 mark_object (&ptr->minibuffer_window); | |
1356 mark_object (&ptr->param_alist); | |
1357 } | |
1358 break; | |
989
dc3fda1e21d0
* alloc.c (Fgarbage_collect): Doc fix.
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1359 #endif /* not MULTI_FRAME */ |
300 | 1360 |
1361 #if 0 | |
1362 case Lisp_Temp_Vector: | |
1363 { | |
1364 register struct Lisp_Vector *ptr = XVECTOR (obj); | |
1365 register int size = ptr->size; | |
1366 register int i; | |
1367 | |
1368 for (i = 0; i < size; i++) /* and then mark its elements */ | |
1369 mark_object (&ptr->contents[i]); | |
1370 } | |
1371 break; | |
1372 #endif /* 0 */ | |
1373 | |
1374 case Lisp_Symbol: | |
1375 { | |
1376 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | |
1377 struct Lisp_Symbol *ptrx; | |
1378 | |
1379 if (XMARKBIT (ptr->plist)) break; | |
1380 XMARK (ptr->plist); | |
1381 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); | |
1382 mark_object (&ptr->name); | |
1383 mark_object ((Lisp_Object *) &ptr->value); | |
1384 mark_object (&ptr->function); | |
1385 mark_object (&ptr->plist); | |
1386 ptr = ptr->next; | |
1387 if (ptr) | |
1388 { | |
1389 ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */ | |
1390 XSETSYMBOL (obj, ptrx); | |
1391 goto loop; | |
1392 } | |
1393 } | |
1394 break; | |
1395 | |
1396 case Lisp_Marker: | |
1397 XMARK (XMARKER (obj)->chain); | |
1398 /* DO NOT mark thru the marker's chain. | |
1399 The buffer's markers chain does not preserve markers from gc; | |
1400 instead, markers are removed from the chain when they are freed by gc. */ | |
1401 break; | |
1402 | |
1403 case Lisp_Cons: | |
1404 case Lisp_Buffer_Local_Value: | |
1405 case Lisp_Some_Buffer_Local_Value: | |
1406 { | |
1407 register struct Lisp_Cons *ptr = XCONS (obj); | |
1408 if (XMARKBIT (ptr->car)) break; | |
1409 XMARK (ptr->car); | |
1410 mark_object (&ptr->car); | |
1411 objptr = &ptr->cdr; | |
1412 obj = ptr->cdr; | |
1413 goto loop; | |
1414 } | |
1415 | |
1416 #ifdef LISP_FLOAT_TYPE | |
1417 case Lisp_Float: | |
1418 XMARK (XFLOAT (obj)->type); | |
1419 break; | |
1420 #endif /* LISP_FLOAT_TYPE */ | |
1421 | |
1422 case Lisp_Buffer: | |
1423 if (!XMARKBIT (XBUFFER (obj)->name)) | |
1424 mark_buffer (obj); | |
1425 break; | |
1426 | |
1427 case Lisp_Int: | |
1428 case Lisp_Void: | |
1429 case Lisp_Subr: | |
1430 case Lisp_Intfwd: | |
1431 case Lisp_Boolfwd: | |
1432 case Lisp_Objfwd: | |
1433 case Lisp_Buffer_Objfwd: | |
1434 case Lisp_Internal_Stream: | |
1435 /* Don't bother with Lisp_Buffer_Objfwd, | |
1436 since all markable slots in current buffer marked anyway. */ | |
1437 /* Don't need to do Lisp_Objfwd, since the places they point | |
1438 are protected with staticpro. */ | |
1439 break; | |
1440 | |
1441 default: | |
1442 abort (); | |
1443 } | |
1444 } | |
1445 | |
1446 /* Mark the pointers in a buffer structure. */ | |
1447 | |
1448 static void | |
1449 mark_buffer (buf) | |
1450 Lisp_Object buf; | |
1451 { | |
1452 Lisp_Object tem; | |
1453 register struct buffer *buffer = XBUFFER (buf); | |
1454 register Lisp_Object *ptr; | |
1455 | |
1456 /* This is the buffer's markbit */ | |
1457 mark_object (&buffer->name); | |
1458 XMARK (buffer->name); | |
1459 | |
1460 #if 0 | |
1461 mark_object (buffer->syntax_table); | |
1462 | |
1463 /* Mark the various string-pointers in the buffer object. | |
1464 Since the strings may be relocated, we must mark them | |
1465 in their actual slots. So gc_sweep must convert each slot | |
1466 back to an ordinary C pointer. */ | |
1467 XSET (*(Lisp_Object *)&buffer->upcase_table, | |
1468 Lisp_String, buffer->upcase_table); | |
1469 mark_object ((Lisp_Object *)&buffer->upcase_table); | |
1470 XSET (*(Lisp_Object *)&buffer->downcase_table, | |
1471 Lisp_String, buffer->downcase_table); | |
1472 mark_object ((Lisp_Object *)&buffer->downcase_table); | |
1473 | |
1474 XSET (*(Lisp_Object *)&buffer->sort_table, | |
1475 Lisp_String, buffer->sort_table); | |
1476 mark_object ((Lisp_Object *)&buffer->sort_table); | |
1477 XSET (*(Lisp_Object *)&buffer->folding_sort_table, | |
1478 Lisp_String, buffer->folding_sort_table); | |
1479 mark_object ((Lisp_Object *)&buffer->folding_sort_table); | |
1480 #endif | |
1481 | |
1482 for (ptr = &buffer->name + 1; | |
1483 (char *)ptr < (char *)buffer + sizeof (struct buffer); | |
1484 ptr++) | |
1485 mark_object (ptr); | |
1486 } | |
1487 | |
1488 /* Find all structures not marked, and free them. */ | |
1489 | |
1490 static void | |
1491 gc_sweep () | |
1492 { | |
1493 total_string_size = 0; | |
1494 compact_strings (); | |
1495 | |
1496 /* Put all unmarked conses on free list */ | |
1497 { | |
1498 register struct cons_block *cblk; | |
1499 register int lim = cons_block_index; | |
1500 register int num_free = 0, num_used = 0; | |
1501 | |
1502 cons_free_list = 0; | |
1503 | |
1504 for (cblk = cons_block; cblk; cblk = cblk->next) | |
1505 { | |
1506 register int i; | |
1507 for (i = 0; i < lim; i++) | |
1508 if (!XMARKBIT (cblk->conses[i].car)) | |
1509 { | |
1510 XFASTINT (cblk->conses[i].car) = (int) cons_free_list; | |
1511 num_free++; | |
1512 cons_free_list = &cblk->conses[i]; | |
1513 } | |
1514 else | |
1515 { | |
1516 num_used++; | |
1517 XUNMARK (cblk->conses[i].car); | |
1518 } | |
1519 lim = CONS_BLOCK_SIZE; | |
1520 } | |
1521 total_conses = num_used; | |
1522 total_free_conses = num_free; | |
1523 } | |
1524 | |
1525 #ifdef LISP_FLOAT_TYPE | |
1526 /* Put all unmarked floats on free list */ | |
1527 { | |
1528 register struct float_block *fblk; | |
1529 register int lim = float_block_index; | |
1530 register int num_free = 0, num_used = 0; | |
1531 | |
1532 float_free_list = 0; | |
1533 | |
1534 for (fblk = float_block; fblk; fblk = fblk->next) | |
1535 { | |
1536 register int i; | |
1537 for (i = 0; i < lim; i++) | |
1538 if (!XMARKBIT (fblk->floats[i].type)) | |
1539 { | |
1540 XFASTINT (fblk->floats[i].type) = (int) float_free_list; | |
1541 num_free++; | |
1542 float_free_list = &fblk->floats[i]; | |
1543 } | |
1544 else | |
1545 { | |
1546 num_used++; | |
1547 XUNMARK (fblk->floats[i].type); | |
1548 } | |
1549 lim = FLOAT_BLOCK_SIZE; | |
1550 } | |
1551 total_floats = num_used; | |
1552 total_free_floats = num_free; | |
1553 } | |
1554 #endif /* LISP_FLOAT_TYPE */ | |
1555 | |
1556 /* Put all unmarked symbols on free list */ | |
1557 { | |
1558 register struct symbol_block *sblk; | |
1559 register int lim = symbol_block_index; | |
1560 register int num_free = 0, num_used = 0; | |
1561 | |
1562 symbol_free_list = 0; | |
1563 | |
1564 for (sblk = symbol_block; sblk; sblk = sblk->next) | |
1565 { | |
1566 register int i; | |
1567 for (i = 0; i < lim; i++) | |
1568 if (!XMARKBIT (sblk->symbols[i].plist)) | |
1569 { | |
1570 XFASTINT (sblk->symbols[i].value) = (int) symbol_free_list; | |
1571 symbol_free_list = &sblk->symbols[i]; | |
1572 num_free++; | |
1573 } | |
1574 else | |
1575 { | |
1576 num_used++; | |
1577 sblk->symbols[i].name | |
1578 = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name); | |
1579 XUNMARK (sblk->symbols[i].plist); | |
1580 } | |
1581 lim = SYMBOL_BLOCK_SIZE; | |
1582 } | |
1583 total_symbols = num_used; | |
1584 total_free_symbols = num_free; | |
1585 } | |
1586 | |
1587 #ifndef standalone | |
1588 /* Put all unmarked markers on free list. | |
1589 Dechain each one first from the buffer it points into. */ | |
1590 { | |
1591 register struct marker_block *mblk; | |
1592 struct Lisp_Marker *tem1; | |
1593 register int lim = marker_block_index; | |
1594 register int num_free = 0, num_used = 0; | |
1595 | |
1596 marker_free_list = 0; | |
1597 | |
1598 for (mblk = marker_block; mblk; mblk = mblk->next) | |
1599 { | |
1600 register int i; | |
1601 for (i = 0; i < lim; i++) | |
1602 if (!XMARKBIT (mblk->markers[i].chain)) | |
1603 { | |
1604 Lisp_Object tem; | |
1605 tem1 = &mblk->markers[i]; /* tem1 avoids Sun compiler bug */ | |
1606 XSET (tem, Lisp_Marker, tem1); | |
1607 unchain_marker (tem); | |
1608 XFASTINT (mblk->markers[i].chain) = (int) marker_free_list; | |
1609 marker_free_list = &mblk->markers[i]; | |
1610 num_free++; | |
1611 } | |
1612 else | |
1613 { | |
1614 num_used++; | |
1615 XUNMARK (mblk->markers[i].chain); | |
1616 } | |
1617 lim = MARKER_BLOCK_SIZE; | |
1618 } | |
1619 | |
1620 total_markers = num_used; | |
1621 total_free_markers = num_free; | |
1622 } | |
1623 | |
1624 /* Free all unmarked buffers */ | |
1625 { | |
1626 register struct buffer *buffer = all_buffers, *prev = 0, *next; | |
1627 | |
1628 while (buffer) | |
1629 if (!XMARKBIT (buffer->name)) | |
1630 { | |
1631 if (prev) | |
1632 prev->next = buffer->next; | |
1633 else | |
1634 all_buffers = buffer->next; | |
1635 next = buffer->next; | |
1636 free (buffer); | |
1637 buffer = next; | |
1638 } | |
1639 else | |
1640 { | |
1641 XUNMARK (buffer->name); | |
1642 | |
1643 #if 0 | |
1644 /* Each `struct Lisp_String *' was turned into a Lisp_Object | |
1645 for purposes of marking and relocation. | |
1646 Turn them back into C pointers now. */ | |
1647 buffer->upcase_table | |
1648 = XSTRING (*(Lisp_Object *)&buffer->upcase_table); | |
1649 buffer->downcase_table | |
1650 = XSTRING (*(Lisp_Object *)&buffer->downcase_table); | |
1651 buffer->sort_table | |
1652 = XSTRING (*(Lisp_Object *)&buffer->sort_table); | |
1653 buffer->folding_sort_table | |
1654 = XSTRING (*(Lisp_Object *)&buffer->folding_sort_table); | |
1655 #endif | |
1656 | |
1657 prev = buffer, buffer = buffer->next; | |
1658 } | |
1659 } | |
1660 | |
1661 #endif /* standalone */ | |
1662 | |
1663 /* Free all unmarked vectors */ | |
1664 { | |
1665 register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next; | |
1666 total_vector_size = 0; | |
1667 | |
1668 while (vector) | |
1669 if (!(vector->size & ARRAY_MARK_FLAG)) | |
1670 { | |
1671 if (prev) | |
1672 prev->next = vector->next; | |
1673 else | |
1674 all_vectors = vector->next; | |
1675 next = vector->next; | |
1676 free (vector); | |
1677 vector = next; | |
1678 } | |
1679 else | |
1680 { | |
1681 vector->size &= ~ARRAY_MARK_FLAG; | |
1682 total_vector_size += vector->size; | |
1683 prev = vector, vector = vector->next; | |
1684 } | |
1685 } | |
1686 | |
1687 /* Free all "large strings" not marked with ARRAY_MARK_FLAG. */ | |
1688 { | |
1689 register struct string_block *sb = large_string_blocks, *prev = 0, *next; | |
1690 | |
1691 while (sb) | |
1692 if (!(((struct Lisp_String *)(&sb->chars[0]))->size & ARRAY_MARK_FLAG)) | |
1693 { | |
1694 if (prev) | |
1695 prev->next = sb->next; | |
1696 else | |
1697 large_string_blocks = sb->next; | |
1698 next = sb->next; | |
1699 free (sb); | |
1700 sb = next; | |
1701 } | |
1702 else | |
1703 { | |
1704 ((struct Lisp_String *)(&sb->chars[0]))->size | |
1705 &= ~ARRAY_MARK_FLAG & ~MARKBIT; | |
1706 total_string_size += ((struct Lisp_String *)(&sb->chars[0]))->size; | |
1707 prev = sb, sb = sb->next; | |
1708 } | |
1709 } | |
1710 } | |
1711 | |
1712 /* Compactify strings, relocate references to them, and | |
1713 free any string blocks that become empty. */ | |
1714 | |
1715 static void | |
1716 compact_strings () | |
1717 { | |
1718 /* String block of old strings we are scanning. */ | |
1719 register struct string_block *from_sb; | |
1720 /* A preceding string block (or maybe the same one) | |
1721 where we are copying the still-live strings to. */ | |
1722 register struct string_block *to_sb; | |
1723 int pos; | |
1724 int to_pos; | |
1725 | |
1726 to_sb = first_string_block; | |
1727 to_pos = 0; | |
1728 | |
1729 /* Scan each existing string block sequentially, string by string. */ | |
1730 for (from_sb = first_string_block; from_sb; from_sb = from_sb->next) | |
1731 { | |
1732 pos = 0; | |
1733 /* POS is the index of the next string in the block. */ | |
1734 while (pos < from_sb->pos) | |
1735 { | |
1736 register struct Lisp_String *nextstr | |
1737 = (struct Lisp_String *) &from_sb->chars[pos]; | |
1738 | |
1739 register struct Lisp_String *newaddr; | |
1740 register int size = nextstr->size; | |
1741 | |
1742 /* NEXTSTR is the old address of the next string. | |
1743 Just skip it if it isn't marked. */ | |
1744 if ((unsigned) size > STRING_BLOCK_SIZE) | |
1745 { | |
1746 /* It is marked, so its size field is really a chain of refs. | |
1747 Find the end of the chain, where the actual size lives. */ | |
1748 while ((unsigned) size > STRING_BLOCK_SIZE) | |
1749 { | |
1750 if (size & 1) size ^= MARKBIT | 1; | |
1751 size = *(int *)size & ~MARKBIT; | |
1752 } | |
1753 | |
1754 total_string_size += size; | |
1755 | |
1756 /* If it won't fit in TO_SB, close it out, | |
1757 and move to the next sb. Keep doing so until | |
1758 TO_SB reaches a large enough, empty enough string block. | |
1759 We know that TO_SB cannot advance past FROM_SB here | |
1760 since FROM_SB is large enough to contain this string. | |
1761 Any string blocks skipped here | |
1762 will be patched out and freed later. */ | |
1763 while (to_pos + STRING_FULLSIZE (size) | |
1764 > max (to_sb->pos, STRING_BLOCK_SIZE)) | |
1765 { | |
1766 to_sb->pos = to_pos; | |
1767 to_sb = to_sb->next; | |
1768 to_pos = 0; | |
1769 } | |
1770 /* Compute new address of this string | |
1771 and update TO_POS for the space being used. */ | |
1772 newaddr = (struct Lisp_String *) &to_sb->chars[to_pos]; | |
1773 to_pos += STRING_FULLSIZE (size); | |
1774 | |
1775 /* Copy the string itself to the new place. */ | |
1776 if (nextstr != newaddr) | |
1777 bcopy (nextstr, newaddr, size + 1 + sizeof (int)); | |
1778 | |
1779 /* Go through NEXTSTR's chain of references | |
1780 and make each slot in the chain point to | |
1781 the new address of this string. */ | |
1782 size = newaddr->size; | |
1783 while ((unsigned) size > STRING_BLOCK_SIZE) | |
1784 { | |
1785 register Lisp_Object *objptr; | |
1786 if (size & 1) size ^= MARKBIT | 1; | |
1787 objptr = (Lisp_Object *)size; | |
1788 | |
1789 size = XFASTINT (*objptr) & ~MARKBIT; | |
1790 if (XMARKBIT (*objptr)) | |
1791 { | |
1792 XSET (*objptr, Lisp_String, newaddr); | |
1793 XMARK (*objptr); | |
1794 } | |
1795 else | |
1796 XSET (*objptr, Lisp_String, newaddr); | |
1797 } | |
1798 /* Store the actual size in the size field. */ | |
1799 newaddr->size = size; | |
1800 } | |
1801 pos += STRING_FULLSIZE (size); | |
1802 } | |
1803 } | |
1804 | |
1805 /* Close out the last string block still used and free any that follow. */ | |
1806 to_sb->pos = to_pos; | |
1807 current_string_block = to_sb; | |
1808 | |
1809 from_sb = to_sb->next; | |
1810 to_sb->next = 0; | |
1811 while (from_sb) | |
1812 { | |
1813 to_sb = from_sb->next; | |
1814 free (from_sb); | |
1815 from_sb = to_sb; | |
1816 } | |
1817 | |
1818 /* Free any empty string blocks further back in the chain. | |
1819 This loop will never free first_string_block, but it is very | |
1820 unlikely that that one will become empty, so why bother checking? */ | |
1821 | |
1822 from_sb = first_string_block; | |
1823 while (to_sb = from_sb->next) | |
1824 { | |
1825 if (to_sb->pos == 0) | |
1826 { | |
1827 if (from_sb->next = to_sb->next) | |
1828 from_sb->next->prev = from_sb; | |
1829 free (to_sb); | |
1830 } | |
1831 else | |
1832 from_sb = to_sb; | |
1833 } | |
1834 } | |
1835 | |
1836 /* Initialization */ | |
1837 | |
1838 init_alloc_once () | |
1839 { | |
1840 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | |
1841 pureptr = 0; | |
356 | 1842 #ifdef HAVE_SHM |
1843 pure_size = PURESIZE; | |
1844 #endif | |
300 | 1845 all_vectors = 0; |
1846 ignore_warnings = 1; | |
1847 init_strings (); | |
1848 init_cons (); | |
1849 init_symbol (); | |
1850 init_marker (); | |
1851 #ifdef LISP_FLOAT_TYPE | |
1852 init_float (); | |
1853 #endif /* LISP_FLOAT_TYPE */ | |
1854 ignore_warnings = 0; | |
1855 gcprolist = 0; | |
1856 staticidx = 0; | |
1857 consing_since_gc = 0; | |
1858 gc_cons_threshold = 100000; | |
1859 #ifdef VIRT_ADDR_VARIES | |
1860 malloc_sbrk_unused = 1<<22; /* A large number */ | |
1861 malloc_sbrk_used = 100000; /* as reasonable as any number */ | |
1862 #endif /* VIRT_ADDR_VARIES */ | |
1863 } | |
1864 | |
1865 init_alloc () | |
1866 { | |
1867 gcprolist = 0; | |
1868 } | |
1869 | |
1870 void | |
1871 syms_of_alloc () | |
1872 { | |
1873 DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold, | |
1874 "*Number of bytes of consing between garbage collections.\n\ | |
1875 Garbage collection can happen automatically once this many bytes have been\n\ | |
1876 allocated since the last garbage collection. All data types count.\n\n\ | |
1877 Garbage collection happens automatically only when `eval' is called.\n\n\ | |
1878 By binding this temporarily to a large number, you can effectively\n\ | |
1879 prevent garbage collection during a part of the program."); | |
1880 | |
1881 DEFVAR_INT ("pure-bytes-used", &pureptr, | |
1882 "Number of bytes of sharable Lisp data allocated so far."); | |
1883 | |
1884 #if 0 | |
1885 DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used, | |
1886 "Number of bytes of unshared memory allocated in this session."); | |
1887 | |
1888 DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused, | |
1889 "Number of bytes of unshared memory remaining available in this session."); | |
1890 #endif | |
1891 | |
1892 DEFVAR_LISP ("purify-flag", &Vpurify_flag, | |
1893 "Non-nil means loading Lisp code in order to dump an executable.\n\ | |
1894 This means that certain objects should be allocated in shared (pure) space."); | |
1895 | |
764 | 1896 DEFVAR_INT ("undo-limit", &undo_limit, |
300 | 1897 "Keep no more undo information once it exceeds this size.\n\ |
764 | 1898 This limit is applied when garbage collection happens.\n\ |
300 | 1899 The size is counted as the number of bytes occupied,\n\ |
1900 which includes both saved text and other data."); | |
764 | 1901 undo_limit = 20000; |
300 | 1902 |
764 | 1903 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit, |
300 | 1904 "Don't keep more than this much size of undo information.\n\ |
1905 A command which pushes past this size is itself forgotten.\n\ | |
764 | 1906 This limit is applied when garbage collection happens.\n\ |
300 | 1907 The size is counted as the number of bytes occupied,\n\ |
1908 which includes both saved text and other data."); | |
764 | 1909 undo_strong_limit = 30000; |
300 | 1910 |
1911 defsubr (&Scons); | |
1912 defsubr (&Slist); | |
1913 defsubr (&Svector); | |
1914 defsubr (&Smake_byte_code); | |
1915 defsubr (&Smake_list); | |
1916 defsubr (&Smake_vector); | |
1917 defsubr (&Smake_string); | |
1918 defsubr (&Smake_rope); | |
1919 defsubr (&Srope_elt); | |
1920 defsubr (&Smake_symbol); | |
1921 defsubr (&Smake_marker); | |
1922 defsubr (&Spurecopy); | |
1923 defsubr (&Sgarbage_collect); | |
1924 } |