aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorGerd Moellmann2000-02-17 15:21:21 +0000
committerGerd Moellmann2000-02-17 15:21:21 +0000
commit344000084d72f603d5953c65f1570841e01b98e4 (patch)
tree7da26d7fa98e6b5a2833b4a9b790a34df89774d4 /src/alloc.c
parent53c80cf65ea01af58e3f71654847d55dfa6f5416 (diff)
downloademacs-344000084d72f603d5953c65f1570841e01b98e4.tar.gz
emacs-344000084d72f603d5953c65f1570841e01b98e4.zip
(mark_object): Don't mark symbol names in pure space.
(gc_sweep): Don't unmark symbol names in pure space. (toplevel): Include setjmp.h. (PURE_POINTER_P): New define. (enum mem_type) [GC_MARK_STACK]: New enumeration. (Vdead) [GC_MARK_STACK]: New variable. (lisp_malloc): Add parameter TYPE, call mem_insert if GC_MARK_STACK is defined. (allocate_buffer): New function. (lisp_free) [GC_MARK_STACK]: Call mem_delete. (free_float) [GC_MARK_STACK]: Set type to Vdead. (free_cons) [GC_MARK_STACK]: Set car to Vdead. (stack_base, mem_root, mem_z) [GC_MARK_STACK]: New variables. (MEM_NIL) [GC_MARK_STACK]: New define. (struct mem_node) [GC_MARK_STACK]: New structure. (mem_init, mem_find, mem_insert, mem_delete, mem_insert_fixup) (mem_delete_fixup, mem_rotate_left, mem_rotate_right) (live_string_p, live_cons_p, live_symbol_p, live_float_p) (live_misc_p, live_vector_p, live_buffer_p, mark_memory) (mark_stack) [GC_MARK_STACK]: New functions. (Fgarbage_collect) [GC_MARK_STACK]: Call mark_stack. (clear_marks): Removed. (gc_sweep): Set free conses' car, free floats' type, free symbols' function to Vdead. Use lisp_free to free buffers. (init_alloc_once): Initialize Vdead. (survives_gc_p): Return non-zero for pure objects. Add comments throughout the file.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c1298
1 files changed, 1169 insertions, 129 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 8152ad2bf1a..04c269deaf0 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
40#include "keyboard.h" 40#include "keyboard.h"
41#include "charset.h" 41#include "charset.h"
42#include "syssignal.h" 42#include "syssignal.h"
43#include <setjmp.h>
43 44
44extern char *sbrk (); 45extern char *sbrk ();
45 46
@@ -149,9 +150,11 @@ int malloc_sbrk_unused;
149int undo_limit; 150int undo_limit;
150int undo_strong_limit; 151int undo_strong_limit;
151 152
152int total_conses, total_markers, total_symbols, total_vector_size; 153/* Number of live and free conses etc. */
153int total_free_conses, total_free_markers, total_free_symbols; 154
154int total_free_floats, total_floats; 155static int total_conses, total_markers, total_symbols, total_vector_size;
156static int total_free_conses, total_free_markers, total_free_symbols;
157static int total_free_floats, total_floats;
155 158
156/* Points to memory space allocated as "spare", to be freed if we run 159/* Points to memory space allocated as "spare", to be freed if we run
157 out of memory. */ 160 out of memory. */
@@ -198,6 +201,14 @@ EMACS_INT pure_size;
198 201
199#endif /* not HAVE_SHM */ 202#endif /* not HAVE_SHM */
200 203
204/* Value is non-zero if P points into pure space. */
205
206#define PURE_POINTER_P(P) \
207 (((PNTR_COMPARISON_TYPE) (P) \
208 < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)) \
209 && ((PNTR_COMPARISON_TYPE) (P) \
210 >= (PNTR_COMPARISON_TYPE) pure))
211
201/* Index in pure at which next pure object will be allocated.. */ 212/* Index in pure at which next pure object will be allocated.. */
202 213
203int pureptr; 214int pureptr;
@@ -234,9 +245,6 @@ static void mark_kboards P_ ((void));
234static void gc_sweep P_ ((void)); 245static void gc_sweep P_ ((void));
235static void mark_glyph_matrix P_ ((struct glyph_matrix *)); 246static void mark_glyph_matrix P_ ((struct glyph_matrix *));
236static void mark_face_cache P_ ((struct face_cache *)); 247static void mark_face_cache P_ ((struct face_cache *));
237#if 0
238static void clear_marks ();
239#endif
240 248
241#ifdef HAVE_WINDOW_SYSTEM 249#ifdef HAVE_WINDOW_SYSTEM
242static void mark_image P_ ((struct image *)); 250static void mark_image P_ ((struct image *));
@@ -249,9 +257,69 @@ static void free_large_strings P_ ((void));
249static void sweep_strings P_ ((void)); 257static void sweep_strings P_ ((void));
250 258
251extern int message_enable_multibyte; 259extern int message_enable_multibyte;
260
261
262#if GC_MARK_STACK
263
264#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
265#include <stdio.h> /* For fprintf. */
266#endif
267
268/* A unique object in pure space used to make some Lisp objects
269 on free lists recognizable in O(1). */
270
271Lisp_Object Vdead;
272
273/* When scanning the C stack for live Lisp objects, Emacs keeps track
274 of what memory allocated via lisp_malloc is intended for what
275 purpose. This enumeration specifies the type of memory. */
276
277enum mem_type
278{
279 MEM_TYPE_NON_LISP,
280 MEM_TYPE_BUFFER,
281 MEM_TYPE_CONS,
282 MEM_TYPE_STRING,
283 MEM_TYPE_MISC,
284 MEM_TYPE_SYMBOL,
285 MEM_TYPE_FLOAT,
286 MEM_TYPE_VECTOR
287};
288
289struct mem_node;
290static void *lisp_malloc P_ ((int, enum mem_type));
291static void mark_stack P_ ((void));
292static void init_stack P_ ((Lisp_Object *));
293static int live_vector_p P_ ((struct mem_node *, void *));
294static int live_buffer_p P_ ((struct mem_node *, void *));
295static int live_string_p P_ ((struct mem_node *, void *));
296static int live_cons_p P_ ((struct mem_node *, void *));
297static int live_symbol_p P_ ((struct mem_node *, void *));
298static int live_float_p P_ ((struct mem_node *, void *));
299static int live_misc_p P_ ((struct mem_node *, void *));
300static void mark_memory P_ ((void *, void *));
301static void mem_init P_ ((void));
302static struct mem_node *mem_insert P_ ((void *, void *, enum mem_type));
303static void mem_insert_fixup P_ ((struct mem_node *));
304static void mem_rotate_left P_ ((struct mem_node *));
305static void mem_rotate_right P_ ((struct mem_node *));
306static void mem_delete P_ ((struct mem_node *));
307static void mem_delete_fixup P_ ((struct mem_node *));
308static INLINE struct mem_node *mem_find P_ ((void *));
309
310#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
311static void check_gcpros P_ ((void));
312#endif
313
314#endif /* GC_MARK_STACK != 0 */
315
252 316
253/* Versions of malloc and realloc that print warnings as memory gets 317/************************************************************************
254 full. */ 318 Malloc
319 ************************************************************************/
320
321/* Write STR to Vstandard_output plus some advice on how to free some
322 memory. Called when memory gets low. */
255 323
256Lisp_Object 324Lisp_Object
257malloc_warning_1 (str) 325malloc_warning_1 (str)
@@ -264,7 +332,9 @@ malloc_warning_1 (str)
264 return Qnil; 332 return Qnil;
265} 333}
266 334
267/* malloc calls this if it finds we are near exhausting storage. */ 335
336/* Function malloc calls this if it finds we are near exhausting
337 storage. */
268 338
269void 339void
270malloc_warning (str) 340malloc_warning (str)
@@ -273,6 +343,9 @@ malloc_warning (str)
273 pending_malloc_warning = str; 343 pending_malloc_warning = str;
274} 344}
275 345
346
347/* Display a malloc warning in buffer *Danger*. */
348
276void 349void
277display_malloc_warning () 350display_malloc_warning ()
278{ 351{
@@ -283,12 +356,14 @@ display_malloc_warning ()
283 internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val); 356 internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val);
284} 357}
285 358
359
286#ifdef DOUG_LEA_MALLOC 360#ifdef DOUG_LEA_MALLOC
287# define BYTES_USED (mallinfo ().arena) 361# define BYTES_USED (mallinfo ().arena)
288#else 362#else
289# define BYTES_USED _bytes_used 363# define BYTES_USED _bytes_used
290#endif 364#endif
291 365
366
292/* Called if malloc returns zero. */ 367/* Called if malloc returns zero. */
293 368
294void 369void
@@ -311,6 +386,7 @@ memory_full ()
311 Fsignal (Qnil, memory_signal_data); 386 Fsignal (Qnil, memory_signal_data);
312} 387}
313 388
389
314/* Called if we can't allocate relocatable space for a buffer. */ 390/* Called if we can't allocate relocatable space for a buffer. */
315 391
316void 392void
@@ -333,8 +409,8 @@ buffer_memory_full ()
333 Fsignal (Qerror, memory_signal_data); 409 Fsignal (Qerror, memory_signal_data);
334} 410}
335 411
336/* Like malloc routines but check for no memory and block interrupt 412
337 input.. */ 413/* Like malloc but check for no memory and block interrupt input.. */
338 414
339long * 415long *
340xmalloc (size) 416xmalloc (size)
@@ -351,6 +427,9 @@ xmalloc (size)
351 return val; 427 return val;
352} 428}
353 429
430
431/* Like realloc but check for no memory and block interrupt input.. */
432
354long * 433long *
355xrealloc (block, size) 434xrealloc (block, size)
356 long *block; 435 long *block;
@@ -371,6 +450,9 @@ xrealloc (block, size)
371 return val; 450 return val;
372} 451}
373 452
453
454/* Like free but block interrupt input.. */
455
374void 456void
375xfree (block) 457xfree (block)
376 long *block; 458 long *block;
@@ -380,24 +462,50 @@ xfree (block)
380 UNBLOCK_INPUT; 462 UNBLOCK_INPUT;
381} 463}
382 464
383/* Like malloc but used for allocating Lisp data. */
384 465
385long * 466/* Like malloc but used for allocating Lisp data. NBYTES is the
386lisp_malloc (size) 467 number of bytes to allocate, TYPE describes the intended use of the
387 int size; 468 allcated memory block (for strings, for conses, ...). */
469
470static void *
471lisp_malloc (nbytes, type)
472 int nbytes;
473 enum mem_type type;
388{ 474{
389 register long *val; 475 register void *val;
390 476
391 BLOCK_INPUT; 477 BLOCK_INPUT;
392 allocating_for_lisp++; 478 allocating_for_lisp++;
393 val = (long *) malloc (size); 479 val = (void *) malloc (nbytes);
394 allocating_for_lisp--; 480 allocating_for_lisp--;
395 UNBLOCK_INPUT; 481 UNBLOCK_INPUT;
396 482
397 if (!val && size) memory_full (); 483 if (!val && nbytes)
484 memory_full ();
485
486#if GC_MARK_STACK
487 if (type != MEM_TYPE_NON_LISP)
488 mem_insert (val, (char *) val + nbytes, type);
489#endif
490
398 return val; 491 return val;
399} 492}
400 493
494
495/* Return a new buffer structure allocated from the heap with
496 a call to lisp_malloc. */
497
498struct buffer *
499allocate_buffer ()
500{
501 return (struct buffer *) lisp_malloc (sizeof (struct buffer),
502 MEM_TYPE_BUFFER);
503}
504
505
506/* Free BLOCK. This must be called to free memory allocated with a
507 call to lisp_malloc. */
508
401void 509void
402lisp_free (block) 510lisp_free (block)
403 long *block; 511 long *block;
@@ -405,9 +513,13 @@ lisp_free (block)
405 BLOCK_INPUT; 513 BLOCK_INPUT;
406 allocating_for_lisp++; 514 allocating_for_lisp++;
407 free (block); 515 free (block);
516#if GC_MARK_STACK
517 mem_delete (mem_find (block));
518#endif
408 allocating_for_lisp--; 519 allocating_for_lisp--;
409 UNBLOCK_INPUT; 520 UNBLOCK_INPUT;
410} 521}
522
411 523
412/* Arranging to disable input signals while we're in malloc. 524/* Arranging to disable input signals while we're in malloc.
413 525
@@ -453,6 +565,7 @@ emacs_blocked_free (ptr)
453 UNBLOCK_INPUT; 565 UNBLOCK_INPUT;
454} 566}
455 567
568
456/* If we released our reserve (due to running out of memory), 569/* If we released our reserve (due to running out of memory),
457 and we have a fair amount free once again, 570 and we have a fair amount free once again,
458 try to set aside another reserve in case we run out once more. 571 try to set aside another reserve in case we run out once more.
@@ -466,6 +579,7 @@ refill_memory_reserve ()
466 spare_memory = (char *) malloc (SPARE_MEMORY); 579 spare_memory = (char *) malloc (SPARE_MEMORY);
467} 580}
468 581
582
469/* This function is the malloc hook that Emacs uses. */ 583/* This function is the malloc hook that Emacs uses. */
470 584
471static void * 585static void *
@@ -488,6 +602,9 @@ emacs_blocked_malloc (size)
488 return value; 602 return value;
489} 603}
490 604
605
606/* This function is the realloc hook that Emacs uses. */
607
491static void * 608static void *
492emacs_blocked_realloc (ptr, size) 609emacs_blocked_realloc (ptr, size)
493 void *ptr; 610 void *ptr;
@@ -504,6 +621,9 @@ emacs_blocked_realloc (ptr, size)
504 return value; 621 return value;
505} 622}
506 623
624
625/* Called from main to set up malloc to use our hooks. */
626
507void 627void
508uninterrupt_malloc () 628uninterrupt_malloc ()
509{ 629{
@@ -528,30 +648,52 @@ uninterrupt_malloc ()
528 Interval Allocation 648 Interval Allocation
529 ***********************************************************************/ 649 ***********************************************************************/
530 650
651/* Number of intervals allocated in an interval_block structure.
652 The 1020 is 1024 minus malloc overhead. */
653
531#define INTERVAL_BLOCK_SIZE \ 654#define INTERVAL_BLOCK_SIZE \
532 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) 655 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval))
533 656
657/* Intervals are allocated in chunks in form of an interval_block
658 structure. */
659
534struct interval_block 660struct interval_block
535{ 661{
536 struct interval_block *next; 662 struct interval_block *next;
537 struct interval intervals[INTERVAL_BLOCK_SIZE]; 663 struct interval intervals[INTERVAL_BLOCK_SIZE];
538}; 664};
539 665
666/* Current interval block. Its `next' pointer points to older
667 blocks. */
668
540struct interval_block *interval_block; 669struct interval_block *interval_block;
670
671/* Index in interval_block above of the next unused interval
672 structure. */
673
541static int interval_block_index; 674static int interval_block_index;
675
676/* Number of free and live intervals. */
677
542static int total_free_intervals, total_intervals; 678static int total_free_intervals, total_intervals;
543 679
680/* List of free intervals. */
681
544INTERVAL interval_free_list; 682INTERVAL interval_free_list;
545 683
546/* Total number of interval blocks now in use. */ 684/* Total number of interval blocks now in use. */
547 685
548int n_interval_blocks; 686int n_interval_blocks;
549 687
688
689/* Initialize interval allocation. */
690
550static void 691static void
551init_intervals () 692init_intervals ()
552{ 693{
553 interval_block 694 interval_block
554 = (struct interval_block *) lisp_malloc (sizeof (struct interval_block)); 695 = (struct interval_block *) lisp_malloc (sizeof *interval_block,
696 MEM_TYPE_NON_LISP);
555 interval_block->next = 0; 697 interval_block->next = 0;
556 bzero ((char *) interval_block->intervals, sizeof interval_block->intervals); 698 bzero ((char *) interval_block->intervals, sizeof interval_block->intervals);
557 interval_block_index = 0; 699 interval_block_index = 0;
@@ -559,7 +701,8 @@ init_intervals ()
559 n_interval_blocks = 1; 701 n_interval_blocks = 1;
560} 702}
561 703
562#define INIT_INTERVALS init_intervals () 704
705/* Return a new interval. */
563 706
564INTERVAL 707INTERVAL
565make_interval () 708make_interval ()
@@ -577,7 +720,8 @@ make_interval ()
577 { 720 {
578 register struct interval_block *newi; 721 register struct interval_block *newi;
579 722
580 newi = (struct interval_block *) lisp_malloc (sizeof (struct interval_block)); 723 newi = (struct interval_block *) lisp_malloc (sizeof *newi,
724 MEM_TYPE_NON_LISP);
581 725
582 VALIDATE_LISP_STORAGE (newi, sizeof *newi); 726 VALIDATE_LISP_STORAGE (newi, sizeof *newi);
583 newi->next = interval_block; 727 newi->next = interval_block;
@@ -593,7 +737,8 @@ make_interval ()
593 return val; 737 return val;
594} 738}
595 739
596/* Mark the pointers of one interval. */ 740
741/* Mark Lisp objects in interval I. */
597 742
598static void 743static void
599mark_interval (i, dummy) 744mark_interval (i, dummy)
@@ -606,6 +751,10 @@ mark_interval (i, dummy)
606 XMARK (i->plist); 751 XMARK (i->plist);
607} 752}
608 753
754
755/* Mark the interval tree rooted in TREE. Don't call this directly;
756 use the macro MARK_INTERVAL_TREE instead. */
757
609static void 758static void
610mark_interval_tree (tree) 759mark_interval_tree (tree)
611 register INTERVAL tree; 760 register INTERVAL tree;
@@ -621,6 +770,9 @@ mark_interval_tree (tree)
621 traverse_intervals (tree, 1, 0, mark_interval, Qnil); 770 traverse_intervals (tree, 1, 0, mark_interval, Qnil);
622} 771}
623 772
773
774/* Mark the interval tree rooted in I. */
775
624#define MARK_INTERVAL_TREE(i) \ 776#define MARK_INTERVAL_TREE(i) \
625 do { \ 777 do { \
626 if (!NULL_INTERVAL_P (i) \ 778 if (!NULL_INTERVAL_P (i) \
@@ -628,6 +780,7 @@ mark_interval_tree (tree)
628 mark_interval_tree (i); \ 780 mark_interval_tree (i); \
629 } while (0) 781 } while (0)
630 782
783
631/* The oddity in the call to XUNMARK is necessary because XUNMARK 784/* The oddity in the call to XUNMARK is necessary because XUNMARK
632 expands to an assignment to its argument, and most C compilers 785 expands to an assignment to its argument, and most C compilers
633 don't support casts on the left operand of `='. */ 786 don't support casts on the left operand of `='. */
@@ -641,6 +794,7 @@ mark_interval_tree (tree)
641 } \ 794 } \
642 } while (0) 795 } while (0)
643 796
797
644 798
645/*********************************************************************** 799/***********************************************************************
646 String Allocation 800 String Allocation
@@ -686,7 +840,7 @@ struct sdata
686{ 840{
687 /* Back-pointer to the string this sdata belongs to. If null, this 841 /* Back-pointer to the string this sdata belongs to. If null, this
688 structure is free, and the NBYTES member of the union below 842 structure is free, and the NBYTES member of the union below
689 contains the string byte size (the same value that STRING_BYTES 843 contains the string's byte size (the same value that STRING_BYTES
690 would return if STRING were non-null). If non-null, STRING_BYTES 844 would return if STRING were non-null). If non-null, STRING_BYTES
691 (STRING) is the size of the data, and DATA contains the string's 845 (STRING) is the size of the data, and DATA contains the string's
692 contents. */ 846 contents. */
@@ -814,7 +968,7 @@ allocate_string ()
814 struct string_block *b; 968 struct string_block *b;
815 int i; 969 int i;
816 970
817 b = (struct string_block *) lisp_malloc (sizeof *b); 971 b = (struct string_block *) lisp_malloc (sizeof *b, MEM_TYPE_STRING);
818 VALIDATE_LISP_STORAGE (b, sizeof *b); 972 VALIDATE_LISP_STORAGE (b, sizeof *b);
819 bzero (b, sizeof *b); 973 bzero (b, sizeof *b);
820 b->next = string_blocks; 974 b->next = string_blocks;
@@ -875,7 +1029,7 @@ allocate_string_data (s, nchars, nbytes)
875 mallopt (M_MMAP_MAX, 0); 1029 mallopt (M_MMAP_MAX, 0);
876#endif 1030#endif
877 1031
878 b = (struct sblock *) lisp_malloc (size); 1032 b = (struct sblock *) lisp_malloc (size, MEM_TYPE_NON_LISP);
879 1033
880#ifdef DOUG_LEA_MALLOC 1034#ifdef DOUG_LEA_MALLOC
881 /* Back to a reasonable maximum of mmap'ed areas. */ 1035 /* Back to a reasonable maximum of mmap'ed areas. */
@@ -893,7 +1047,7 @@ allocate_string_data (s, nchars, nbytes)
893 < needed)) 1047 < needed))
894 { 1048 {
895 /* Not enough room in the current sblock. */ 1049 /* Not enough room in the current sblock. */
896 b = (struct sblock *) lisp_malloc (SBLOCK_SIZE); 1050 b = (struct sblock *) lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP);
897 b->next_free = &b->first_data; 1051 b->next_free = &b->first_data;
898 b->first_data.string = NULL; 1052 b->first_data.string = NULL;
899 b->next = NULL; 1053 b->next = NULL;
@@ -997,7 +1151,7 @@ sweep_strings ()
997 } 1151 }
998 } 1152 }
999 1153
1000 /* Free blocks that are contain free Lisp_Strings only, except 1154 /* Free blocks that contain free Lisp_Strings only, except
1001 the first two of them. */ 1155 the first two of them. */
1002 if (nfree == STRINGS_IN_STRING_BLOCK 1156 if (nfree == STRINGS_IN_STRING_BLOCK
1003 && total_free_strings > STRINGS_IN_STRING_BLOCK) 1157 && total_free_strings > STRINGS_IN_STRING_BLOCK)
@@ -1190,6 +1344,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil.")
1190 slot `size' of the struct Lisp_Bool_Vector. */ 1344 slot `size' of the struct Lisp_Bool_Vector. */
1191 val = Fmake_vector (make_number (length_in_elts + 1), Qnil); 1345 val = Fmake_vector (make_number (length_in_elts + 1), Qnil);
1192 p = XBOOL_VECTOR (val); 1346 p = XBOOL_VECTOR (val);
1347
1193 /* Get rid of any bits that would cause confusion. */ 1348 /* Get rid of any bits that would cause confusion. */
1194 p->vector_size = 0; 1349 p->vector_size = 0;
1195 XSETBOOL_VECTOR (val, p); 1350 XSETBOOL_VECTOR (val, p);
@@ -1198,6 +1353,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil.")
1198 real_init = (NILP (init) ? 0 : -1); 1353 real_init = (NILP (init) ? 0 : -1);
1199 for (i = 0; i < length_in_chars ; i++) 1354 for (i = 0; i < length_in_chars ; i++)
1200 p->data[i] = real_init; 1355 p->data[i] = real_init;
1356
1201 /* Clear the extraneous bits in the last byte. */ 1357 /* Clear the extraneous bits in the last byte. */
1202 if (XINT (length) != length_in_chars * BITS_PER_CHAR) 1358 if (XINT (length) != length_in_chars * BITS_PER_CHAR)
1203 XBOOL_VECTOR (val)->data[length_in_chars - 1] 1359 XBOOL_VECTOR (val)->data[length_in_chars - 1]
@@ -1361,19 +1517,30 @@ struct float_block
1361 struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; 1517 struct Lisp_Float floats[FLOAT_BLOCK_SIZE];
1362}; 1518};
1363 1519
1520/* Current float_block. */
1521
1364struct float_block *float_block; 1522struct float_block *float_block;
1523
1524/* Index of first unused Lisp_Float in the current float_block. */
1525
1365int float_block_index; 1526int float_block_index;
1366 1527
1367/* Total number of float blocks now in use. */ 1528/* Total number of float blocks now in use. */
1368 1529
1369int n_float_blocks; 1530int n_float_blocks;
1370 1531
1532/* Free-list of Lisp_Floats. */
1533
1371struct Lisp_Float *float_free_list; 1534struct Lisp_Float *float_free_list;
1372 1535
1536
1537/* Initialze float allocation. */
1538
1373void 1539void
1374init_float () 1540init_float ()
1375{ 1541{
1376 float_block = (struct float_block *) lisp_malloc (sizeof (struct float_block)); 1542 float_block = (struct float_block *) lisp_malloc (sizeof *float_block,
1543 MEM_TYPE_FLOAT);
1377 float_block->next = 0; 1544 float_block->next = 0;
1378 bzero ((char *) float_block->floats, sizeof float_block->floats); 1545 bzero ((char *) float_block->floats, sizeof float_block->floats);
1379 float_block_index = 0; 1546 float_block_index = 0;
@@ -1381,16 +1548,23 @@ init_float ()
1381 n_float_blocks = 1; 1548 n_float_blocks = 1;
1382} 1549}
1383 1550
1384/* Explicitly free a float cell. */ 1551
1552/* Explicitly free a float cell by putting it on the free-list. */
1385 1553
1386void 1554void
1387free_float (ptr) 1555free_float (ptr)
1388 struct Lisp_Float *ptr; 1556 struct Lisp_Float *ptr;
1389{ 1557{
1390 *(struct Lisp_Float **)&ptr->data = float_free_list; 1558 *(struct Lisp_Float **)&ptr->data = float_free_list;
1559#if GC_MARK_STACK
1560 ptr->type = Vdead;
1561#endif
1391 float_free_list = ptr; 1562 float_free_list = ptr;
1392} 1563}
1393 1564
1565
1566/* Return a new float object with value FLOAT_VALUE. */
1567
1394Lisp_Object 1568Lisp_Object
1395make_float (float_value) 1569make_float (float_value)
1396 double float_value; 1570 double float_value;
@@ -1410,7 +1584,8 @@ make_float (float_value)
1410 { 1584 {
1411 register struct float_block *new; 1585 register struct float_block *new;
1412 1586
1413 new = (struct float_block *) lisp_malloc (sizeof (struct float_block)); 1587 new = (struct float_block *) lisp_malloc (sizeof *new,
1588 MEM_TYPE_FLOAT);
1414 VALIDATE_LISP_STORAGE (new, sizeof *new); 1589 VALIDATE_LISP_STORAGE (new, sizeof *new);
1415 new->next = float_block; 1590 new->next = float_block;
1416 float_block = new; 1591 float_block = new;
@@ -1451,19 +1626,30 @@ struct cons_block
1451 struct Lisp_Cons conses[CONS_BLOCK_SIZE]; 1626 struct Lisp_Cons conses[CONS_BLOCK_SIZE];
1452}; 1627};
1453 1628
1629/* Current cons_block. */
1630
1454struct cons_block *cons_block; 1631struct cons_block *cons_block;
1632
1633/* Index of first unused Lisp_Cons in the current block. */
1634
1455int cons_block_index; 1635int cons_block_index;
1456 1636
1637/* Free-list of Lisp_Cons structures. */
1638
1457struct Lisp_Cons *cons_free_list; 1639struct Lisp_Cons *cons_free_list;
1458 1640
1459/* Total number of cons blocks now in use. */ 1641/* Total number of cons blocks now in use. */
1460 1642
1461int n_cons_blocks; 1643int n_cons_blocks;
1462 1644
1645
1646/* Initialize cons allocation. */
1647
1463void 1648void
1464init_cons () 1649init_cons ()
1465{ 1650{
1466 cons_block = (struct cons_block *) lisp_malloc (sizeof (struct cons_block)); 1651 cons_block = (struct cons_block *) lisp_malloc (sizeof *cons_block,
1652 MEM_TYPE_CONS);
1467 cons_block->next = 0; 1653 cons_block->next = 0;
1468 bzero ((char *) cons_block->conses, sizeof cons_block->conses); 1654 bzero ((char *) cons_block->conses, sizeof cons_block->conses);
1469 cons_block_index = 0; 1655 cons_block_index = 0;
@@ -1471,16 +1657,21 @@ init_cons ()
1471 n_cons_blocks = 1; 1657 n_cons_blocks = 1;
1472} 1658}
1473 1659
1474/* Explicitly free a cons cell. */ 1660
1661/* Explicitly free a cons cell by putting it on the free-list. */
1475 1662
1476void 1663void
1477free_cons (ptr) 1664free_cons (ptr)
1478 struct Lisp_Cons *ptr; 1665 struct Lisp_Cons *ptr;
1479{ 1666{
1480 *(struct Lisp_Cons **)&ptr->cdr = cons_free_list; 1667 *(struct Lisp_Cons **)&ptr->cdr = cons_free_list;
1668#if GC_MARK_STACK
1669 ptr->car = Vdead;
1670#endif
1481 cons_free_list = ptr; 1671 cons_free_list = ptr;
1482} 1672}
1483 1673
1674
1484DEFUN ("cons", Fcons, Scons, 2, 2, 0, 1675DEFUN ("cons", Fcons, Scons, 2, 2, 0,
1485 "Create a new cons, give it CAR and CDR as components, and return it.") 1676 "Create a new cons, give it CAR and CDR as components, and return it.")
1486 (car, cdr) 1677 (car, cdr)
@@ -1500,7 +1691,8 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
1500 if (cons_block_index == CONS_BLOCK_SIZE) 1691 if (cons_block_index == CONS_BLOCK_SIZE)
1501 { 1692 {
1502 register struct cons_block *new; 1693 register struct cons_block *new;
1503 new = (struct cons_block *) lisp_malloc (sizeof (struct cons_block)); 1694 new = (struct cons_block *) lisp_malloc (sizeof *new,
1695 MEM_TYPE_CONS);
1504 VALIDATE_LISP_STORAGE (new, sizeof *new); 1696 VALIDATE_LISP_STORAGE (new, sizeof *new);
1505 new->next = cons_block; 1697 new->next = cons_block;
1506 cons_block = new; 1698 cons_block = new;
@@ -1517,7 +1709,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
1517 return val; 1709 return val;
1518} 1710}
1519 1711
1520 1712
1521/* Make a list of 2, 3, 4 or 5 specified objects. */ 1713/* Make a list of 2, 3, 4 or 5 specified objects. */
1522 1714
1523Lisp_Object 1715Lisp_Object
@@ -1527,6 +1719,7 @@ list2 (arg1, arg2)
1527 return Fcons (arg1, Fcons (arg2, Qnil)); 1719 return Fcons (arg1, Fcons (arg2, Qnil));
1528} 1720}
1529 1721
1722
1530Lisp_Object 1723Lisp_Object
1531list3 (arg1, arg2, arg3) 1724list3 (arg1, arg2, arg3)
1532 Lisp_Object arg1, arg2, arg3; 1725 Lisp_Object arg1, arg2, arg3;
@@ -1534,6 +1727,7 @@ list3 (arg1, arg2, arg3)
1534 return Fcons (arg1, Fcons (arg2, Fcons (arg3, Qnil))); 1727 return Fcons (arg1, Fcons (arg2, Fcons (arg3, Qnil)));
1535} 1728}
1536 1729
1730
1537Lisp_Object 1731Lisp_Object
1538list4 (arg1, arg2, arg3, arg4) 1732list4 (arg1, arg2, arg3, arg4)
1539 Lisp_Object arg1, arg2, arg3, arg4; 1733 Lisp_Object arg1, arg2, arg3, arg4;
@@ -1541,6 +1735,7 @@ list4 (arg1, arg2, arg3, arg4)
1541 return Fcons (arg1, Fcons (arg2, Fcons (arg3, Fcons (arg4, Qnil)))); 1735 return Fcons (arg1, Fcons (arg2, Fcons (arg3, Fcons (arg4, Qnil))));
1542} 1736}
1543 1737
1738
1544Lisp_Object 1739Lisp_Object
1545list5 (arg1, arg2, arg3, arg4, arg5) 1740list5 (arg1, arg2, arg3, arg4, arg5)
1546 Lisp_Object arg1, arg2, arg3, arg4, arg5; 1741 Lisp_Object arg1, arg2, arg3, arg4, arg5;
@@ -1549,6 +1744,7 @@ list5 (arg1, arg2, arg3, arg4, arg5)
1549 Fcons (arg5, Qnil))))); 1744 Fcons (arg5, Qnil)))));
1550} 1745}
1551 1746
1747
1552DEFUN ("list", Flist, Slist, 0, MANY, 0, 1748DEFUN ("list", Flist, Slist, 0, MANY, 0,
1553 "Return a newly created list with specified arguments as elements.\n\ 1749 "Return a newly created list with specified arguments as elements.\n\
1554Any number of arguments, even zero arguments, are allowed.") 1750Any number of arguments, even zero arguments, are allowed.")
@@ -1567,6 +1763,7 @@ Any number of arguments, even zero arguments, are allowed.")
1567 return val; 1763 return val;
1568} 1764}
1569 1765
1766
1570DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, 1767DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
1571 "Return a newly created list of length LENGTH, with each element being INIT.") 1768 "Return a newly created list of length LENGTH, with each element being INIT.")
1572 (length, init) 1769 (length, init)
@@ -1590,39 +1787,49 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
1590 Vector Allocation 1787 Vector Allocation
1591 ***********************************************************************/ 1788 ***********************************************************************/
1592 1789
1790/* Singly-linked list of all vectors. */
1791
1593struct Lisp_Vector *all_vectors; 1792struct Lisp_Vector *all_vectors;
1594 1793
1595/* Total number of vector-like objects now in use. */ 1794/* Total number of vector-like objects now in use. */
1596 1795
1597int n_vectors; 1796int n_vectors;
1598 1797
1798
1799/* Value is a pointer to a newly allocated Lisp_Vector structure
1800 with room for LEN Lisp_Objects. */
1801
1599struct Lisp_Vector * 1802struct Lisp_Vector *
1600allocate_vectorlike (len) 1803allocate_vectorlike (len)
1601 EMACS_INT len; 1804 EMACS_INT len;
1602{ 1805{
1603 struct Lisp_Vector *p; 1806 struct Lisp_Vector *p;
1807 int nbytes;
1604 1808
1605#ifdef DOUG_LEA_MALLOC 1809#ifdef DOUG_LEA_MALLOC
1606 /* Prevent mmap'ing the chunk (which is potentially very large).. */ 1810 /* Prevent mmap'ing the chunk (which is potentially very large).. */
1607 mallopt (M_MMAP_MAX, 0); 1811 mallopt (M_MMAP_MAX, 0);
1608#endif 1812#endif
1609 p = (struct Lisp_Vector *)lisp_malloc (sizeof (struct Lisp_Vector) 1813
1610 + (len - 1) * sizeof (Lisp_Object)); 1814 nbytes = sizeof *p + (len - 1) * sizeof p->contents[0];
1815 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTOR);
1816
1611#ifdef DOUG_LEA_MALLOC 1817#ifdef DOUG_LEA_MALLOC
1612 /* Back to a reasonable maximum of mmap'ed areas. */ 1818 /* Back to a reasonable maximum of mmap'ed areas. */
1613 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 1819 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
1614#endif 1820#endif
1821
1615 VALIDATE_LISP_STORAGE (p, 0); 1822 VALIDATE_LISP_STORAGE (p, 0);
1616 consing_since_gc += (sizeof (struct Lisp_Vector) 1823 consing_since_gc += nbytes;
1617 + (len - 1) * sizeof (Lisp_Object));
1618 vector_cells_consed += len; 1824 vector_cells_consed += len;
1619 n_vectors++;
1620 1825
1621 p->next = all_vectors; 1826 p->next = all_vectors;
1622 all_vectors = p; 1827 all_vectors = p;
1828 ++n_vectors;
1623 return p; 1829 return p;
1624} 1830}
1625 1831
1832
1626DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, 1833DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
1627 "Return a newly created vector of length LENGTH, with each element being INIT.\n\ 1834 "Return a newly created vector of length LENGTH, with each element being INIT.\n\
1628See also the function `vector'.") 1835See also the function `vector'.")
@@ -1646,6 +1853,7 @@ See also the function `vector'.")
1646 return vector; 1853 return vector;
1647} 1854}
1648 1855
1856
1649DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0, 1857DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0,
1650 "Return a newly created char-table, with purpose PURPOSE.\n\ 1858 "Return a newly created char-table, with purpose PURPOSE.\n\
1651Each element is initialized to INIT, which defaults to nil.\n\ 1859Each element is initialized to INIT, which defaults to nil.\n\
@@ -1671,6 +1879,7 @@ The property's value should be an integer between 0 and 10.")
1671 return vector; 1879 return vector;
1672} 1880}
1673 1881
1882
1674/* Return a newly created sub char table with default value DEFALT. 1883/* Return a newly created sub char table with default value DEFALT.
1675 Since a sub char table does not appear as a top level Emacs Lisp 1884 Since a sub char table does not appear as a top level Emacs Lisp
1676 object, we don't need a Lisp interface to make it. */ 1885 object, we don't need a Lisp interface to make it. */
@@ -1687,6 +1896,7 @@ make_sub_char_table (defalt)
1687 return vector; 1896 return vector;
1688} 1897}
1689 1898
1899
1690DEFUN ("vector", Fvector, Svector, 0, MANY, 0, 1900DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
1691 "Return a newly created vector with specified arguments as elements.\n\ 1901 "Return a newly created vector with specified arguments as elements.\n\
1692Any number of arguments, even zero arguments, are allowed.") 1902Any number of arguments, even zero arguments, are allowed.")
@@ -1706,6 +1916,7 @@ Any number of arguments, even zero arguments, are allowed.")
1706 return val; 1916 return val;
1707} 1917}
1708 1918
1919
1709DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, 1920DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0,
1710 "Create a byte-code object with specified arguments as elements.\n\ 1921 "Create a byte-code object with specified arguments as elements.\n\
1711The arguments should be the arglist, bytecode-string, constant vector,\n\ 1922The arguments should be the arglist, bytecode-string, constant vector,\n\
@@ -1736,6 +1947,7 @@ significance.")
1736 return val; 1947 return val;
1737} 1948}
1738 1949
1950
1739 1951
1740/*********************************************************************** 1952/***********************************************************************
1741 Symbol Allocation 1953 Symbol Allocation
@@ -1754,19 +1966,28 @@ struct symbol_block
1754 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; 1966 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
1755}; 1967};
1756 1968
1969/* Current symbol block and index of first unused Lisp_Symbol
1970 structure in it. */
1971
1757struct symbol_block *symbol_block; 1972struct symbol_block *symbol_block;
1758int symbol_block_index; 1973int symbol_block_index;
1759 1974
1975/* List of free symbols. */
1976
1760struct Lisp_Symbol *symbol_free_list; 1977struct Lisp_Symbol *symbol_free_list;
1761 1978
1762/* Total number of symbol blocks now in use. */ 1979/* Total number of symbol blocks now in use. */
1763 1980
1764int n_symbol_blocks; 1981int n_symbol_blocks;
1765 1982
1983
1984/* Initialize symbol allocation. */
1985
1766void 1986void
1767init_symbol () 1987init_symbol ()
1768{ 1988{
1769 symbol_block = (struct symbol_block *) lisp_malloc (sizeof (struct symbol_block)); 1989 symbol_block = (struct symbol_block *) lisp_malloc (sizeof *symbol_block,
1990 MEM_TYPE_SYMBOL);
1770 symbol_block->next = 0; 1991 symbol_block->next = 0;
1771 bzero ((char *) symbol_block->symbols, sizeof symbol_block->symbols); 1992 bzero ((char *) symbol_block->symbols, sizeof symbol_block->symbols);
1772 symbol_block_index = 0; 1993 symbol_block_index = 0;
@@ -1774,6 +1995,7 @@ init_symbol ()
1774 n_symbol_blocks = 1; 1995 n_symbol_blocks = 1;
1775} 1996}
1776 1997
1998
1777DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, 1999DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
1778 "Return a newly allocated uninterned symbol whose name is NAME.\n\ 2000 "Return a newly allocated uninterned symbol whose name is NAME.\n\
1779Its value and function definition are void, and its property list is nil.") 2001Its value and function definition are void, and its property list is nil.")
@@ -1795,7 +2017,8 @@ Its value and function definition are void, and its property list is nil.")
1795 if (symbol_block_index == SYMBOL_BLOCK_SIZE) 2017 if (symbol_block_index == SYMBOL_BLOCK_SIZE)
1796 { 2018 {
1797 struct symbol_block *new; 2019 struct symbol_block *new;
1798 new = (struct symbol_block *) lisp_malloc (sizeof (struct symbol_block)); 2020 new = (struct symbol_block *) lisp_malloc (sizeof *new,
2021 MEM_TYPE_SYMBOL);
1799 VALIDATE_LISP_STORAGE (new, sizeof *new); 2022 VALIDATE_LISP_STORAGE (new, sizeof *new);
1800 new->next = symbol_block; 2023 new->next = symbol_block;
1801 symbol_block = new; 2024 symbol_block = new;
@@ -1820,7 +2043,7 @@ Its value and function definition are void, and its property list is nil.")
1820 2043
1821 2044
1822/*********************************************************************** 2045/***********************************************************************
1823 Marker Allocation 2046 Marker (Misc) Allocation
1824 ***********************************************************************/ 2047 ***********************************************************************/
1825 2048
1826/* Allocation of markers and other objects that share that structure. 2049/* Allocation of markers and other objects that share that structure.
@@ -1847,7 +2070,8 @@ int n_marker_blocks;
1847void 2070void
1848init_marker () 2071init_marker ()
1849{ 2072{
1850 marker_block = (struct marker_block *) lisp_malloc (sizeof (struct marker_block)); 2073 marker_block = (struct marker_block *) lisp_malloc (sizeof *marker_block,
2074 MEM_TYPE_MISC);
1851 marker_block->next = 0; 2075 marker_block->next = 0;
1852 bzero ((char *) marker_block->markers, sizeof marker_block->markers); 2076 bzero ((char *) marker_block->markers, sizeof marker_block->markers);
1853 marker_block_index = 0; 2077 marker_block_index = 0;
@@ -1872,7 +2096,8 @@ allocate_misc ()
1872 if (marker_block_index == MARKER_BLOCK_SIZE) 2096 if (marker_block_index == MARKER_BLOCK_SIZE)
1873 { 2097 {
1874 struct marker_block *new; 2098 struct marker_block *new;
1875 new = (struct marker_block *) lisp_malloc (sizeof (struct marker_block)); 2099 new = (struct marker_block *) lisp_malloc (sizeof *new,
2100 MEM_TYPE_MISC);
1876 VALIDATE_LISP_STORAGE (new, sizeof *new); 2101 VALIDATE_LISP_STORAGE (new, sizeof *new);
1877 new->next = marker_block; 2102 new->next = marker_block;
1878 marker_block = new; 2103 marker_block = new;
@@ -1962,6 +2187,816 @@ make_event_array (nargs, args)
1962 2187
1963 2188
1964 2189
2190/************************************************************************
2191 C Stack Marking
2192 ************************************************************************/
2193
2194#if GC_MARK_STACK
2195
2196
2197/* Base address of stack. Set in main. */
2198
2199Lisp_Object *stack_base;
2200
2201/* A node in the red-black tree describing allocated memory containing
2202 Lisp data. Each such block is recorded with its start and end
2203 address when it is allocated, and removed from the tree when it
2204 is freed.
2205
2206 A red-black tree is a balanced binary tree with the following
2207 properties:
2208
2209 1. Every node is either red or black.
2210 2. Every leaf is black.
2211 3. If a node is red, then both of its children are black.
2212 4. Every simple path from a node to a descendant leaf contains
2213 the same number of black nodes.
2214 5. The root is always black.
2215
2216 When nodes are inserted into the tree, or deleted from the tree,
2217 the tree is "fixed" so that these properties are always true.
2218
2219 A red-black tree with N internal nodes has height at most 2
2220 log(N+1). Searches, insertions and deletions are done in O(log N).
2221 Please see a text book about data structures for a detailed
2222 description of red-black trees. Any book worth its salt should
2223 describe them. */
2224
2225struct mem_node
2226{
2227 struct mem_node *left, *right, *parent;
2228
2229 /* Start and end of allocated region. */
2230 void *start, *end;
2231
2232 /* Node color. */
2233 enum {MEM_BLACK, MEM_RED} color;
2234
2235 /* Memory type. */
2236 enum mem_type type;
2237};
2238
2239/* Root of the tree describing allocated Lisp memory. */
2240
2241static struct mem_node *mem_root;
2242
2243/* Sentinel node of the tree. */
2244
2245static struct mem_node mem_z;
2246#define MEM_NIL &mem_z
2247
2248
2249/* Initialize this part of alloc.c. */
2250
2251static void
2252mem_init ()
2253{
2254 mem_z.left = mem_z.right = MEM_NIL;
2255 mem_z.parent = NULL;
2256 mem_z.color = MEM_BLACK;
2257 mem_z.start = mem_z.end = NULL;
2258 mem_root = MEM_NIL;
2259}
2260
2261
2262/* Value is a pointer to the mem_node containing START. Value is
2263 MEM_NIL if there is no node in the tree containing START. */
2264
2265static INLINE struct mem_node *
2266mem_find (start)
2267 void *start;
2268{
2269 struct mem_node *p;
2270
2271 /* Make the search always successful to speed up the loop below. */
2272 mem_z.start = start;
2273 mem_z.end = (char *) start + 1;
2274
2275 p = mem_root;
2276 while (start < p->start || start >= p->end)
2277 p = start < p->start ? p->left : p->right;
2278 return p;
2279}
2280
2281
2282/* Insert a new node into the tree for a block of memory with start
2283 address START, end address END, and type TYPE. Value is a
2284 pointer to the node that was inserted. */
2285
2286static struct mem_node *
2287mem_insert (start, end, type)
2288 void *start, *end;
2289 enum mem_type type;
2290{
2291 struct mem_node *c, *parent, *x;
2292
2293 /* See where in the tree a node for START belongs. In this
2294 particular application, it shouldn't happen that a node is already
2295 present. For debugging purposes, let's check that. */
2296 c = mem_root;
2297 parent = NULL;
2298
2299#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS
2300
2301 while (c != MEM_NIL)
2302 {
2303 if (start >= c->start && start < c->end)
2304 abort ();
2305 parent = c;
2306 c = start < c->start ? c->left : c->right;
2307 }
2308
2309#else /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */
2310
2311 while (c != MEM_NIL)
2312 {
2313 parent = c;
2314 c = start < c->start ? c->left : c->right;
2315 }
2316
2317#endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */
2318
2319 /* Create a new node. */
2320 x = (struct mem_node *) xmalloc (sizeof *x);
2321 x->start = start;
2322 x->end = end;
2323 x->type = type;
2324 x->parent = parent;
2325 x->left = x->right = MEM_NIL;
2326 x->color = MEM_RED;
2327
2328 /* Insert it as child of PARENT or install it as root. */
2329 if (parent)
2330 {
2331 if (start < parent->start)
2332 parent->left = x;
2333 else
2334 parent->right = x;
2335 }
2336 else
2337 mem_root = x;
2338
2339 /* Re-establish red-black tree properties. */
2340 mem_insert_fixup (x);
2341 return x;
2342}
2343
2344
2345/* Re-establish the red-black properties of the tree, and thereby
2346 balance the tree, after node X has been inserted; X is always red. */
2347
2348static void
2349mem_insert_fixup (x)
2350 struct mem_node *x;
2351{
2352 while (x != mem_root && x->parent->color == MEM_RED)
2353 {
2354 /* X is red and its parent is red. This is a violation of
2355 red-black tree property #3. */
2356
2357 if (x->parent == x->parent->parent->left)
2358 {
2359 /* We're on the left side of our grandparent, and Y is our
2360 "uncle". */
2361 struct mem_node *y = x->parent->parent->right;
2362
2363 if (y->color == MEM_RED)
2364 {
2365 /* Uncle and parent are red but should be black because
2366 X is red. Change the colors accordingly and proceed
2367 with the grandparent. */
2368 x->parent->color = MEM_BLACK;
2369 y->color = MEM_BLACK;
2370 x->parent->parent->color = MEM_RED;
2371 x = x->parent->parent;
2372 }
2373 else
2374 {
2375 /* Parent and uncle have different colors; parent is
2376 red, uncle is black. */
2377 if (x == x->parent->right)
2378 {
2379 x = x->parent;
2380 mem_rotate_left (x);
2381 }
2382
2383 x->parent->color = MEM_BLACK;
2384 x->parent->parent->color = MEM_RED;
2385 mem_rotate_right (x->parent->parent);
2386 }
2387 }
2388 else
2389 {
2390 /* This is the symmetrical case of above. */
2391 struct mem_node *y = x->parent->parent->left;
2392
2393 if (y->color == MEM_RED)
2394 {
2395 x->parent->color = MEM_BLACK;
2396 y->color = MEM_BLACK;
2397 x->parent->parent->color = MEM_RED;
2398 x = x->parent->parent;
2399 }
2400 else
2401 {
2402 if (x == x->parent->left)
2403 {
2404 x = x->parent;
2405 mem_rotate_right (x);
2406 }
2407
2408 x->parent->color = MEM_BLACK;
2409 x->parent->parent->color = MEM_RED;
2410 mem_rotate_left (x->parent->parent);
2411 }
2412 }
2413 }
2414
2415 /* The root may have been changed to red due to the algorithm. Set
2416 it to black so that property #5 is satisfied. */
2417 mem_root->color = MEM_BLACK;
2418}
2419
2420
2421/* (x) (y)
2422 / \ / \
2423 a (y) ===> (x) c
2424 / \ / \
2425 b c a b */
2426
2427static void
2428mem_rotate_left (x)
2429 struct mem_node *x;
2430{
2431 struct mem_node *y;
2432
2433 /* Turn y's left sub-tree into x's right sub-tree. */
2434 y = x->right;
2435 x->right = y->left;
2436 if (y->left != MEM_NIL)
2437 y->left->parent = x;
2438
2439 /* Y's parent was x's parent. */
2440 if (y != MEM_NIL)
2441 y->parent = x->parent;
2442
2443 /* Get the parent to point to y instead of x. */
2444 if (x->parent)
2445 {
2446 if (x == x->parent->left)
2447 x->parent->left = y;
2448 else
2449 x->parent->right = y;
2450 }
2451 else
2452 mem_root = y;
2453
2454 /* Put x on y's left. */
2455 y->left = x;
2456 if (x != MEM_NIL)
2457 x->parent = y;
2458}
2459
2460
2461/* (x) (Y)
2462 / \ / \
2463 (y) c ===> a (x)
2464 / \ / \
2465 a b b c */
2466
2467static void
2468mem_rotate_right (x)
2469 struct mem_node *x;
2470{
2471 struct mem_node *y = x->left;
2472
2473 x->left = y->right;
2474 if (y->right != MEM_NIL)
2475 y->right->parent = x;
2476
2477 if (y != MEM_NIL)
2478 y->parent = x->parent;
2479 if (x->parent)
2480 {
2481 if (x == x->parent->right)
2482 x->parent->right = y;
2483 else
2484 x->parent->left = y;
2485 }
2486 else
2487 mem_root = y;
2488
2489 y->right = x;
2490 if (x != MEM_NIL)
2491 x->parent = y;
2492}
2493
2494
2495/* Delete node Z from the tree. If Z is null or MEM_NIL, do nothing. */
2496
2497static void
2498mem_delete (z)
2499 struct mem_node *z;
2500{
2501 struct mem_node *x, *y;
2502
2503 if (!z || z == MEM_NIL)
2504 return;
2505
2506 if (z->left == MEM_NIL || z->right == MEM_NIL)
2507 y = z;
2508 else
2509 {
2510 y = z->right;
2511 while (y->left != MEM_NIL)
2512 y = y->left;
2513 }
2514
2515 if (y->left != MEM_NIL)
2516 x = y->left;
2517 else
2518 x = y->right;
2519
2520 x->parent = y->parent;
2521 if (y->parent)
2522 {
2523 if (y == y->parent->left)
2524 y->parent->left = x;
2525 else
2526 y->parent->right = x;
2527 }
2528 else
2529 mem_root = x;
2530
2531 if (y != z)
2532 {
2533 z->start = y->start;
2534 z->end = y->end;
2535 z->type = y->type;
2536 }
2537
2538 if (y->color == MEM_BLACK)
2539 mem_delete_fixup (x);
2540 xfree (y);
2541}
2542
2543
2544/* Re-establish the red-black properties of the tree, after a
2545 deletion. */
2546
2547static void
2548mem_delete_fixup (x)
2549 struct mem_node *x;
2550{
2551 while (x != mem_root && x->color == MEM_BLACK)
2552 {
2553 if (x == x->parent->left)
2554 {
2555 struct mem_node *w = x->parent->right;
2556
2557 if (w->color == MEM_RED)
2558 {
2559 w->color = MEM_BLACK;
2560 x->parent->color = MEM_RED;
2561 mem_rotate_left (x->parent);
2562 w = x->parent->right;
2563 }
2564
2565 if (w->left->color == MEM_BLACK && w->right->color == MEM_BLACK)
2566 {
2567 w->color = MEM_RED;
2568 x = x->parent;
2569 }
2570 else
2571 {
2572 if (w->right->color == MEM_BLACK)
2573 {
2574 w->left->color = MEM_BLACK;
2575 w->color = MEM_RED;
2576 mem_rotate_right (w);
2577 w = x->parent->right;
2578 }
2579 w->color = x->parent->color;
2580 x->parent->color = MEM_BLACK;
2581 w->right->color = MEM_BLACK;
2582 mem_rotate_left (x->parent);
2583 x = mem_root;
2584 }
2585 }
2586 else
2587 {
2588 struct mem_node *w = x->parent->left;
2589
2590 if (w->color == MEM_RED)
2591 {
2592 w->color = MEM_BLACK;
2593 x->parent->color = MEM_RED;
2594 mem_rotate_right (x->parent);
2595 w = x->parent->left;
2596 }
2597
2598 if (w->right->color == MEM_BLACK && w->left->color == MEM_BLACK)
2599 {
2600 w->color = MEM_RED;
2601 x = x->parent;
2602 }
2603 else
2604 {
2605 if (w->left->color == MEM_BLACK)
2606 {
2607 w->right->color = MEM_BLACK;
2608 w->color = MEM_RED;
2609 mem_rotate_left (w);
2610 w = x->parent->left;
2611 }
2612
2613 w->color = x->parent->color;
2614 x->parent->color = MEM_BLACK;
2615 w->left->color = MEM_BLACK;
2616 mem_rotate_right (x->parent);
2617 x = mem_root;
2618 }
2619 }
2620 }
2621
2622 x->color = MEM_BLACK;
2623}
2624
2625
2626/* Value is non-zero if P is a pointer to a live Lisp string on
2627 the heap. M is a pointer to the mem_block for P. */
2628
2629static INLINE int
2630live_string_p (m, p)
2631 struct mem_node *m;
2632 void *p;
2633{
2634 if (m->type == MEM_TYPE_STRING)
2635 {
2636 struct string_block *b = (struct string_block *) m->start;
2637 int offset = (char *) p - (char *) &b->strings[0];
2638
2639 /* P must point to the start of a Lisp_String structure, and it
2640 must not be on the free-list. */
2641 return (offset % sizeof b->strings[0] == 0
2642 && ((struct Lisp_String *) p)->data != NULL);
2643 }
2644 else
2645 return 0;
2646}
2647
2648
2649/* Value is non-zero if P is a pointer to a live Lisp cons on
2650 the heap. M is a pointer to the mem_block for P. */
2651
2652static INLINE int
2653live_cons_p (m, p)
2654 struct mem_node *m;
2655 void *p;
2656{
2657 if (m->type == MEM_TYPE_CONS)
2658 {
2659 struct cons_block *b = (struct cons_block *) m->start;
2660 int offset = (char *) p - (char *) &b->conses[0];
2661
2662 /* P must point to the start of a Lisp_Cons, not be
2663 one of the unused cells in the current cons block,
2664 and not be on the free-list. */
2665 return (offset % sizeof b->conses[0] == 0
2666 && (b != cons_block
2667 || offset / sizeof b->conses[0] < cons_block_index)
2668 && !EQ (((struct Lisp_Cons *) p)->car, Vdead));
2669 }
2670 else
2671 return 0;
2672}
2673
2674
2675/* Value is non-zero if P is a pointer to a live Lisp symbol on
2676 the heap. M is a pointer to the mem_block for P. */
2677
2678static INLINE int
2679live_symbol_p (m, p)
2680 struct mem_node *m;
2681 void *p;
2682{
2683 if (m->type == MEM_TYPE_SYMBOL)
2684 {
2685 struct symbol_block *b = (struct symbol_block *) m->start;
2686 int offset = (char *) p - (char *) &b->symbols[0];
2687
2688 /* P must point to the start of a Lisp_Symbol, not be
2689 one of the unused cells in the current symbol block,
2690 and not be on the free-list. */
2691 return (offset % sizeof b->symbols[0] == 0
2692 && (b != symbol_block
2693 || offset / sizeof b->symbols[0] < symbol_block_index)
2694 && !EQ (((struct Lisp_Symbol *) p)->function, Vdead));
2695 }
2696 else
2697 return 0;
2698}
2699
2700
2701/* Value is non-zero if P is a pointer to a live Lisp float on
2702 the heap. M is a pointer to the mem_block for P. */
2703
2704static INLINE int
2705live_float_p (m, p)
2706 struct mem_node *m;
2707 void *p;
2708{
2709 if (m->type == MEM_TYPE_FLOAT)
2710 {
2711 struct float_block *b = (struct float_block *) m->start;
2712 int offset = (char *) p - (char *) &b->floats[0];
2713
2714 /* P must point to the start of a Lisp_Float, not be
2715 one of the unused cells in the current float block,
2716 and not be on the free-list. */
2717 return (offset % sizeof b->floats[0] == 0
2718 && (b != float_block
2719 || offset / sizeof b->floats[0] < float_block_index)
2720 && !EQ (((struct Lisp_Float *) p)->type, Vdead));
2721 }
2722 else
2723 return 0;
2724}
2725
2726
2727/* Value is non-zero if P is a pointer to a live Lisp Misc on
2728 the heap. M is a pointer to the mem_block for P. */
2729
2730static INLINE int
2731live_misc_p (m, p)
2732 struct mem_node *m;
2733 void *p;
2734{
2735 if (m->type == MEM_TYPE_MISC)
2736 {
2737 struct marker_block *b = (struct marker_block *) m->start;
2738 int offset = (char *) p - (char *) &b->markers[0];
2739
2740 /* P must point to the start of a Lisp_Misc, not be
2741 one of the unused cells in the current misc block,
2742 and not be on the free-list. */
2743 return (offset % sizeof b->markers[0] == 0
2744 && (b != marker_block
2745 || offset / sizeof b->markers[0] < marker_block_index)
2746 && ((union Lisp_Misc *) p)->u_marker.type != Lisp_Misc_Free);
2747 }
2748 else
2749 return 0;
2750}
2751
2752
2753/* Value is non-zero if P is a pointer to a live vector-like object.
2754 M is a pointer to the mem_block for P. */
2755
2756static INLINE int
2757live_vector_p (m, p)
2758 struct mem_node *m;
2759 void *p;
2760{
2761 return m->type == MEM_TYPE_VECTOR && p == m->start;
2762}
2763
2764
2765/* Value is non-zero of P is a pointer to a live buffer. M is a
2766 pointer to the mem_block for P. */
2767
2768static INLINE int
2769live_buffer_p (m, p)
2770 struct mem_node *m;
2771 void *p;
2772{
2773 /* P must point to the start of the block, and the buffer
2774 must not have been killed. */
2775 return (m->type == MEM_TYPE_BUFFER
2776 && p == m->start
2777 && !NILP (((struct buffer *) p)->name));
2778}
2779
2780
2781#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2782
2783/* Array of objects that are kept alive because the C stack contains
2784 a pattern that looks like a reference to them . */
2785
2786#define MAX_ZOMBIES 10
2787static Lisp_Object zombies[MAX_ZOMBIES];
2788
2789/* Number of zombie objects. */
2790
2791static int nzombies;
2792
2793/* Number of garbage collections. */
2794
2795static int ngcs;
2796
2797/* Average percentage of zombies per collection. */
2798
2799static double avg_zombies;
2800
2801/* Max. number of live and zombie objects. */
2802
2803static int max_live, max_zombies;
2804
2805/* Average number of live objects per GC. */
2806
2807static double avg_live;
2808
2809DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "",
2810 "Show information about live and zombie objects.")
2811 ()
2812{
2813 Lisp_Object args[7];
2814 args[0] = build_string ("%d GCs, avg live/zombies = %.2f/%.2f (%f%%), max %d/%d");
2815 args[1] = make_number (ngcs);
2816 args[2] = make_float (avg_live);
2817 args[3] = make_float (avg_zombies);
2818 args[4] = make_float (avg_zombies / avg_live / 100);
2819 args[5] = make_number (max_live);
2820 args[6] = make_number (max_zombies);
2821 return Fmessage (7, args);
2822}
2823
2824#endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */
2825
2826
2827/* Mark Lisp objects in the address range START..END. */
2828
2829static void
2830mark_memory (start, end)
2831 void *start, *end;
2832{
2833 Lisp_Object *p;
2834
2835#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2836 nzombies = 0;
2837#endif
2838
2839 /* Make START the pointer to the start of the memory region,
2840 if it isn't already. */
2841 if (end < start)
2842 {
2843 void *tem = start;
2844 start = end;
2845 end = tem;
2846 }
2847
2848 for (p = (Lisp_Object *) start; (void *) p < end; ++p)
2849 {
2850 void *po = (void *) XPNTR (*p);
2851 struct mem_node *m = mem_find (po);
2852
2853 if (m != MEM_NIL)
2854 {
2855 int mark_p = 0;
2856
2857 switch (XGCTYPE (*p))
2858 {
2859 case Lisp_String:
2860 mark_p = (live_string_p (m, po)
2861 && !STRING_MARKED_P ((struct Lisp_String *) po));
2862 break;
2863
2864 case Lisp_Cons:
2865 mark_p = (live_cons_p (m, po)
2866 && !XMARKBIT (XCONS (*p)->car));
2867 break;
2868
2869 case Lisp_Symbol:
2870 mark_p = (live_symbol_p (m, po)
2871 && !XMARKBIT (XSYMBOL (*p)->plist));
2872 break;
2873
2874 case Lisp_Float:
2875 mark_p = (live_float_p (m, po)
2876 && !XMARKBIT (XFLOAT (*p)->type));
2877 break;
2878
2879 case Lisp_Vectorlike:
2880 /* Note: can't check GC_BUFFERP before we know it's a
2881 buffer because checking that dereferences the pointer
2882 PO which might point anywhere. */
2883 if (live_vector_p (m, po))
2884 mark_p = (!GC_SUBRP (*p)
2885 && !(XVECTOR (*p)->size & ARRAY_MARK_FLAG));
2886 else if (live_buffer_p (m, po))
2887 mark_p = GC_BUFFERP (*p) && !XMARKBIT (XBUFFER (*p)->name);
2888 break;
2889
2890 case Lisp_Misc:
2891 if (live_misc_p (m, po))
2892 {
2893 switch (XMISCTYPE (*p))
2894 {
2895 case Lisp_Misc_Marker:
2896 mark_p = !XMARKBIT (XMARKER (*p)->chain);
2897 break;
2898
2899 case Lisp_Misc_Buffer_Local_Value:
2900 case Lisp_Misc_Some_Buffer_Local_Value:
2901 mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (*p)->realvalue);
2902 break;
2903
2904 case Lisp_Misc_Overlay:
2905 mark_p = !XMARKBIT (XOVERLAY (*p)->plist);
2906 break;
2907 }
2908 }
2909 break;
2910 }
2911
2912 if (mark_p)
2913 {
2914#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2915 if (nzombies < MAX_ZOMBIES)
2916 zombies[nzombies] = *p;
2917 ++nzombies;
2918#endif
2919 mark_object (p);
2920 }
2921 }
2922 }
2923}
2924
2925
2926#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
2927
2928/* Abort if anything GCPRO'd doesn't survive the GC. */
2929
2930static void
2931check_gcpros ()
2932{
2933 struct gcpro *p;
2934 int i;
2935
2936 for (p = gcprolist; p; p = p->next)
2937 for (i = 0; i < p->nvars; ++i)
2938 if (!survives_gc_p (p->var[i]))
2939 abort ();
2940}
2941
2942#elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2943
2944static void
2945dump_zombies ()
2946{
2947 int i;
2948
2949 fprintf (stderr, "\nZombies kept alive = %d:\n", nzombies);
2950 for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i)
2951 {
2952 fprintf (stderr, " %d = ", i);
2953 debug_print (zombies[i]);
2954 }
2955}
2956
2957#endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */
2958
2959
2960/* Mark live Lisp objects on the C stack. */
2961
2962static void
2963mark_stack ()
2964{
2965 jmp_buf j;
2966 int stack_grows_down_p = (char *) &j > (char *) stack_base;
2967 void *end;
2968
2969 /* This trick flushes the register windows so that all the state of
2970 the process is contained in the stack. */
2971#ifdef sparc
2972 asm ("ta 3");
2973#endif
2974
2975 /* Save registers that we need to see on the stack. We need to see
2976 registers used to hold register variables and registers used to
2977 pass parameters. */
2978#ifdef GC_SAVE_REGISTERS_ON_STACK
2979 GC_SAVE_REGISTERS_ON_STACK (end);
2980#else
2981 setjmp (j);
2982 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
2983#endif
2984
2985 /* This assumes that the stack is a contiguous region in memory. If
2986 that's not the case, something has to be done here to iterate over
2987 the stack segments. */
2988 mark_memory (stack_base, end);
2989
2990#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
2991 check_gcpros ();
2992#endif
2993}
2994
2995
2996#endif /* GC_MARK_STACK != 0 */
2997
2998
2999
1965/*********************************************************************** 3000/***********************************************************************
1966 Pure Storage Management 3001 Pure Storage Management
1967 ***********************************************************************/ 3002 ***********************************************************************/
@@ -2010,6 +3045,9 @@ make_pure_string (data, nchars, nbytes, multibyte)
2010} 3045}
2011 3046
2012 3047
3048/* Return a cons allocated from pure space. Give it pure copies
3049 of CAR as car and CDR as cdr. */
3050
2013Lisp_Object 3051Lisp_Object
2014pure_cons (car, cdr) 3052pure_cons (car, cdr)
2015 Lisp_Object car, cdr; 3053 Lisp_Object car, cdr;
@@ -2026,6 +3064,8 @@ pure_cons (car, cdr)
2026} 3064}
2027 3065
2028 3066
3067/* Value is a float object with value NUM allocated from pure space. */
3068
2029Lisp_Object 3069Lisp_Object
2030make_pure_float (num) 3070make_pure_float (num)
2031 double num; 3071 double num;
@@ -2062,12 +3102,17 @@ make_pure_float (num)
2062 return new; 3102 return new;
2063} 3103}
2064 3104
3105
3106/* Return a vector with room for LEN Lisp_Objects allocated from
3107 pure space. */
3108
2065Lisp_Object 3109Lisp_Object
2066make_pure_vector (len) 3110make_pure_vector (len)
2067 EMACS_INT len; 3111 EMACS_INT len;
2068{ 3112{
2069 register Lisp_Object new; 3113 register Lisp_Object new;
2070 register EMACS_INT size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object); 3114 register EMACS_INT size = (sizeof (struct Lisp_Vector)
3115 + (len - 1) * sizeof (Lisp_Object));
2071 3116
2072 if (pureptr + size > PURESIZE) 3117 if (pureptr + size > PURESIZE)
2073 error ("Pure Lisp storage exhausted"); 3118 error ("Pure Lisp storage exhausted");
@@ -2078,6 +3123,7 @@ make_pure_vector (len)
2078 return new; 3123 return new;
2079} 3124}
2080 3125
3126
2081DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, 3127DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
2082 "Make a copy of OBJECT in pure storage.\n\ 3128 "Make a copy of OBJECT in pure storage.\n\
2083Recursively copies contents of vectors and cons cells.\n\ 3129Recursively copies contents of vectors and cons cells.\n\
@@ -2123,17 +3169,26 @@ Does not copy symbols. Copies strings without text properties.")
2123 return obj; 3169 return obj;
2124} 3170}
2125 3171
3172
2126 3173
3174/***********************************************************************
3175 Protection from GC
3176 ***********************************************************************/
3177
2127/* Recording what needs to be marked for gc. */ 3178/* Recording what needs to be marked for gc. */
2128 3179
2129struct gcpro *gcprolist; 3180struct gcpro *gcprolist;
2130 3181
2131#define NSTATICS 1024 3182/* Addresses of staticpro'd variables. */
2132 3183
3184#define NSTATICS 1024
2133Lisp_Object *staticvec[NSTATICS] = {0}; 3185Lisp_Object *staticvec[NSTATICS] = {0};
2134 3186
3187/* Index of next unused slot in staticvec. */
3188
2135int staticidx = 0; 3189int staticidx = 0;
2136 3190
3191
2137/* Put an entry in staticvec, pointing at the variable with address 3192/* Put an entry in staticvec, pointing at the variable with address
2138 VARADDRESS. */ 3193 VARADDRESS. */
2139 3194
@@ -2151,9 +3206,6 @@ struct catchtag
2151 Lisp_Object tag; 3206 Lisp_Object tag;
2152 Lisp_Object val; 3207 Lisp_Object val;
2153 struct catchtag *next; 3208 struct catchtag *next;
2154#if 0 /* We don't need this for GC purposes */
2155 jmp_buf jmp;
2156#endif
2157}; 3209};
2158 3210
2159struct backtrace 3211struct backtrace
@@ -2167,8 +3219,11 @@ struct backtrace
2167 char evalargs; 3219 char evalargs;
2168}; 3220};
2169 3221
3222
2170 3223
2171/* Garbage collection! */ 3224/***********************************************************************
3225 Protection from GC
3226 ***********************************************************************/
2172 3227
2173/* Temporarily prevent garbage collection. */ 3228/* Temporarily prevent garbage collection. */
2174 3229
@@ -2186,6 +3241,7 @@ inhibit_garbage_collection ()
2186 return count; 3241 return count;
2187} 3242}
2188 3243
3244
2189DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", 3245DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
2190 "Reclaim storage for Lisp objects no longer needed.\n\ 3246 "Reclaim storage for Lisp objects no longer needed.\n\
2191Returns info on amount of space in use:\n\ 3247Returns info on amount of space in use:\n\
@@ -2275,6 +3331,11 @@ Garbage collection happens automatically if you cons more than\n\
2275 3331
2276 for (i = 0; i < staticidx; i++) 3332 for (i = 0; i < staticidx; i++)
2277 mark_object (staticvec[i]); 3333 mark_object (staticvec[i]);
3334
3335#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
3336 || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
3337 mark_stack ();
3338#else
2278 for (tail = gcprolist; tail; tail = tail->next) 3339 for (tail = gcprolist; tail; tail = tail->next)
2279 for (i = 0; i < tail->nvars; i++) 3340 for (i = 0; i < tail->nvars; i++)
2280 if (!XMARKBIT (tail->var[i])) 3341 if (!XMARKBIT (tail->var[i]))
@@ -2282,6 +3343,8 @@ Garbage collection happens automatically if you cons more than\n\
2282 mark_object (&tail->var[i]); 3343 mark_object (&tail->var[i]);
2283 XMARK (tail->var[i]); 3344 XMARK (tail->var[i]);
2284 } 3345 }
3346#endif
3347
2285 mark_byte_stack (); 3348 mark_byte_stack ();
2286 for (bind = specpdl; bind != specpdl_ptr; bind++) 3349 for (bind = specpdl; bind != specpdl_ptr; bind++)
2287 { 3350 {
@@ -2358,13 +3421,21 @@ Garbage collection happens automatically if you cons more than\n\
2358 } 3421 }
2359 } 3422 }
2360 3423
3424#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
3425 mark_stack ();
3426#endif
3427
2361 gc_sweep (); 3428 gc_sweep ();
2362 3429
2363 /* Clear the mark bits that we set in certain root slots. */ 3430 /* Clear the mark bits that we set in certain root slots. */
2364 3431
3432#if (GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE \
3433 || GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES)
2365 for (tail = gcprolist; tail; tail = tail->next) 3434 for (tail = gcprolist; tail; tail = tail->next)
2366 for (i = 0; i < tail->nvars; i++) 3435 for (i = 0; i < tail->nvars; i++)
2367 XUNMARK (tail->var[i]); 3436 XUNMARK (tail->var[i]);
3437#endif
3438
2368 unmark_byte_stack (); 3439 unmark_byte_stack ();
2369 for (backlist = backtrace_list; backlist; backlist = backlist->next) 3440 for (backlist = backtrace_list; backlist; backlist = backlist->next)
2370 { 3441 {
@@ -2379,6 +3450,10 @@ Garbage collection happens automatically if you cons more than\n\
2379 XUNMARK (buffer_defaults.name); 3450 XUNMARK (buffer_defaults.name);
2380 XUNMARK (buffer_local_symbols.name); 3451 XUNMARK (buffer_local_symbols.name);
2381 3452
3453#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES && 0
3454 dump_zombies ();
3455#endif
3456
2382 UNBLOCK_INPUT; 3457 UNBLOCK_INPUT;
2383 3458
2384 /* clear_marks (); */ 3459 /* clear_marks (); */
@@ -2413,67 +3488,25 @@ Garbage collection happens automatically if you cons more than\n\
2413 total[6] = Fcons (make_number (total_strings), 3488 total[6] = Fcons (make_number (total_strings),
2414 make_number (total_free_strings)); 3489 make_number (total_free_strings));
2415 3490
2416 return Flist (7, total); 3491#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2417}
2418
2419#if 0
2420static void
2421clear_marks ()
2422{
2423 /* Clear marks on all conses */
2424 {
2425 register struct cons_block *cblk;
2426 register int lim = cons_block_index;
2427
2428 for (cblk = cons_block; cblk; cblk = cblk->next)
2429 {
2430 register int i;
2431 for (i = 0; i < lim; i++)
2432 XUNMARK (cblk->conses[i].car);
2433 lim = CONS_BLOCK_SIZE;
2434 }
2435 }
2436 /* Clear marks on all symbols */
2437 { 3492 {
2438 register struct symbol_block *sblk; 3493 /* Compute average percentage of zombies. */
2439 register int lim = symbol_block_index; 3494 double nlive = 0;
2440 3495
2441 for (sblk = symbol_block; sblk; sblk = sblk->next) 3496 for (i = 0; i < 7; ++i)
2442 { 3497 nlive += XFASTINT (XCAR (total[i]));
2443 register int i; 3498
2444 for (i = 0; i < lim; i++) 3499 avg_live = (avg_live * ngcs + nlive) / (ngcs + 1);
2445 { 3500 max_live = max (nlive, max_live);
2446 XUNMARK (sblk->symbols[i].plist); 3501 avg_zombies = (avg_zombies * ngcs + nzombies) / (ngcs + 1);
2447 } 3502 max_zombies = max (nzombies, max_zombies);
2448 lim = SYMBOL_BLOCK_SIZE; 3503 ++ngcs;
2449 } 3504 }
2450 } 3505#endif
2451 /* Clear marks on all markers */
2452 {
2453 register struct marker_block *sblk;
2454 register int lim = marker_block_index;
2455
2456 for (sblk = marker_block; sblk; sblk = sblk->next)
2457 {
2458 register int i;
2459 for (i = 0; i < lim; i++)
2460 if (sblk->markers[i].u_marker.type == Lisp_Misc_Marker)
2461 XUNMARK (sblk->markers[i].u_marker.chain);
2462 lim = MARKER_BLOCK_SIZE;
2463 }
2464 }
2465 /* Clear mark bits on all buffers */
2466 {
2467 register struct buffer *nextb = all_buffers;
2468 3506
2469 while (nextb) 3507 return Flist (7, total);
2470 {
2471 XUNMARK (nextb->name);
2472 nextb = nextb->next;
2473 }
2474 }
2475} 3508}
2476#endif 3509
2477 3510
2478/* Mark Lisp objects in glyph matrix MATRIX. Currently the 3511/* Mark Lisp objects in glyph matrix MATRIX. Currently the
2479 only interesting objects referenced from glyphs are strings. */ 3512 only interesting objects referenced from glyphs are strings. */
@@ -2502,6 +3535,7 @@ mark_glyph_matrix (matrix)
2502 } 3535 }
2503} 3536}
2504 3537
3538
2505/* Mark Lisp faces in the face cache C. */ 3539/* Mark Lisp faces in the face cache C. */
2506 3540
2507static void 3541static void
@@ -2575,8 +3609,7 @@ mark_object (argptr)
2575 loop2: 3609 loop2:
2576 XUNMARK (obj); 3610 XUNMARK (obj);
2577 3611
2578 if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) 3612 if (PURE_POINTER_P ((PNTR_COMPARISON_TYPE) XPNTR (obj)))
2579 && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure)
2580 return; 3613 return;
2581 3614
2582 last_marked[last_marked_index++] = objptr; 3615 last_marked[last_marked_index++] = objptr;
@@ -2772,8 +3805,10 @@ mark_object (argptr)
2772 mark_object ((Lisp_Object *) &ptr->value); 3805 mark_object ((Lisp_Object *) &ptr->value);
2773 mark_object (&ptr->function); 3806 mark_object (&ptr->function);
2774 mark_object (&ptr->plist); 3807 mark_object (&ptr->plist);
3808
3809 if (!PURE_POINTER_P (ptr->name))
3810 MARK_STRING (ptr->name);
2775 MARK_INTERVAL_TREE (ptr->name->intervals); 3811 MARK_INTERVAL_TREE (ptr->name->intervals);
2776 MARK_STRING (ptr->name);
2777 3812
2778 /* Note that we do not mark the obarray of the symbol. 3813 /* Note that we do not mark the obarray of the symbol.
2779 It is safe not to do so because nothing accesses that 3814 It is safe not to do so because nothing accesses that
@@ -3048,7 +4083,7 @@ survives_gc_p (obj)
3048 abort (); 4083 abort ();
3049 } 4084 }
3050 4085
3051 return survives_p; 4086 return survives_p || PURE_POINTER_P ((void *) XPNTR (obj));
3052} 4087}
3053 4088
3054 4089
@@ -3083,6 +4118,9 @@ gc_sweep ()
3083 this_free++; 4118 this_free++;
3084 *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; 4119 *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list;
3085 cons_free_list = &cblk->conses[i]; 4120 cons_free_list = &cblk->conses[i];
4121#if GC_MARK_STACK
4122 cons_free_list->car = Vdead;
4123#endif
3086 } 4124 }
3087 else 4125 else
3088 { 4126 {
@@ -3130,6 +4168,9 @@ gc_sweep ()
3130 this_free++; 4168 this_free++;
3131 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; 4169 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list;
3132 float_free_list = &fblk->floats[i]; 4170 float_free_list = &fblk->floats[i];
4171#if GC_MARK_STACK
4172 float_free_list->type = Vdead;
4173#endif
3133 } 4174 }
3134 else 4175 else
3135 { 4176 {
@@ -3226,12 +4267,16 @@ gc_sweep ()
3226 { 4267 {
3227 *(struct Lisp_Symbol **)&sblk->symbols[i].value = symbol_free_list; 4268 *(struct Lisp_Symbol **)&sblk->symbols[i].value = symbol_free_list;
3228 symbol_free_list = &sblk->symbols[i]; 4269 symbol_free_list = &sblk->symbols[i];
4270#if GC_MARK_STACK
4271 symbol_free_list->function = Vdead;
4272#endif
3229 this_free++; 4273 this_free++;
3230 } 4274 }
3231 else 4275 else
3232 { 4276 {
3233 num_used++; 4277 num_used++;
3234 UNMARK_STRING (sblk->symbols[i].name); 4278 if (!PURE_POINTER_P (sblk->symbols[i].name))
4279 UNMARK_STRING (sblk->symbols[i].name);
3235 XUNMARK (sblk->symbols[i].plist); 4280 XUNMARK (sblk->symbols[i].plist);
3236 } 4281 }
3237 lim = SYMBOL_BLOCK_SIZE; 4282 lim = SYMBOL_BLOCK_SIZE;
@@ -3356,7 +4401,7 @@ gc_sweep ()
3356 else 4401 else
3357 all_buffers = buffer->next; 4402 all_buffers = buffer->next;
3358 next = buffer->next; 4403 next = buffer->next;
3359 xfree (buffer); 4404 lisp_free (buffer);
3360 buffer = next; 4405 buffer = next;
3361 } 4406 }
3362 else 4407 else
@@ -3375,11 +4420,6 @@ gc_sweep ()
3375 while (vector) 4420 while (vector)
3376 if (!(vector->size & ARRAY_MARK_FLAG)) 4421 if (!(vector->size & ARRAY_MARK_FLAG))
3377 { 4422 {
3378#if 0
3379 if ((vector->size & (PSEUDOVECTOR_FLAG | PVEC_HASH_TABLE))
3380 == (PSEUDOVECTOR_FLAG | PVEC_HASH_TABLE))
3381 fprintf (stderr, "Freeing hash table %p\n", vector);
3382#endif
3383 if (prev) 4423 if (prev)
3384 prev->next = vector->next; 4424 prev->next = vector->next;
3385 else 4425 else
@@ -3464,6 +4504,10 @@ init_alloc_once ()
3464{ 4504{
3465 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ 4505 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */
3466 pureptr = 0; 4506 pureptr = 0;
4507#if GC_MARK_STACK
4508 mem_init ();
4509 Vdead = make_pure_string ("DEAD", 4, 4, 0);
4510#endif
3467#ifdef HAVE_SHM 4511#ifdef HAVE_SHM
3468 pure_size = PURESIZE; 4512 pure_size = PURESIZE;
3469#endif 4513#endif
@@ -3479,7 +4523,7 @@ init_alloc_once ()
3479 init_symbol (); 4523 init_symbol ();
3480 init_marker (); 4524 init_marker ();
3481 init_float (); 4525 init_float ();
3482 INIT_INTERVALS; 4526 init_intervals ();
3483 4527
3484#ifdef REL_ALLOC 4528#ifdef REL_ALLOC
3485 malloc_hysteresis = 32; 4529 malloc_hysteresis = 32;
@@ -3546,14 +4590,6 @@ prevent garbage collection during a part of the program.");
3546 DEFVAR_INT ("strings-consed", &strings_consed, 4590 DEFVAR_INT ("strings-consed", &strings_consed,
3547 "Number of strings that have been consed so far."); 4591 "Number of strings that have been consed so far.");
3548 4592
3549#if 0
3550 DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used,
3551 "Number of bytes of unshared memory allocated in this session.");
3552
3553 DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused,
3554 "Number of bytes of unshared memory remaining available in this session.");
3555#endif
3556
3557 DEFVAR_LISP ("purify-flag", &Vpurify_flag, 4593 DEFVAR_LISP ("purify-flag", &Vpurify_flag,
3558 "Non-nil means loading Lisp code in order to dump an executable.\n\ 4594 "Non-nil means loading Lisp code in order to dump an executable.\n\
3559This means that certain objects should be allocated in shared (pure) space."); 4595This means that certain objects should be allocated in shared (pure) space.");
@@ -3604,4 +4640,8 @@ which includes both saved text and other data.");
3604 defsubr (&Sgarbage_collect); 4640 defsubr (&Sgarbage_collect);
3605 defsubr (&Smemory_limit); 4641 defsubr (&Smemory_limit);
3606 defsubr (&Smemory_use_counts); 4642 defsubr (&Smemory_use_counts);
4643
4644#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
4645 defsubr (&Sgc_status);
4646#endif
3607} 4647}