comparison src/alloc.c @ 89909:68c22ea6027c

Sync to HEAD
author Kenichi Handa <handa@m17n.org>
date Fri, 16 Apr 2004 12:51:06 +0000
parents c9f7a2f363ca
children 4c90ffeb71c5
comparison
equal deleted inserted replaced
89908:ee1402f7b568 89909:68c22ea6027c
1 /* Storage allocation and gc for GNU Emacs Lisp interpreter. 1 /* Storage allocation and gc for GNU Emacs Lisp interpreter.
2 Copyright (C) 1985, 86, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001, 2002, 2003 2 Copyright (C) 1985,86,88,93,94,95,97,98,1999,2000,01,02,03,2004
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
6 6
7 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
28 #endif 28 #endif
29 29
30 /* Note that this declares bzero on OSF/1. How dumb. */ 30 /* Note that this declares bzero on OSF/1. How dumb. */
31 31
32 #include <signal.h> 32 #include <signal.h>
33
34 /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
35 memory. Can do this only if using gmalloc.c. */
36
37 #if defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC
38 #undef GC_MALLOC_CHECK
39 #endif
40 33
41 /* This file is part of the core Lisp implementation, and thus must 34 /* This file is part of the core Lisp implementation, and thus must
42 deal with the real data structures. If the Lisp implementation is 35 deal with the real data structures. If the Lisp implementation is
43 replaced, this file likely will not be used. */ 36 replaced, this file likely will not be used. */
44 37
53 #include "frame.h" 46 #include "frame.h"
54 #include "blockinput.h" 47 #include "blockinput.h"
55 #include "character.h" 48 #include "character.h"
56 #include "syssignal.h" 49 #include "syssignal.h"
57 #include <setjmp.h> 50 #include <setjmp.h>
51
52 /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
53 memory. Can do this only if using gmalloc.c. */
54
55 #if defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC
56 #undef GC_MALLOC_CHECK
57 #endif
58 58
59 #ifdef HAVE_UNISTD_H 59 #ifdef HAVE_UNISTD_H
60 #include <unistd.h> 60 #include <unistd.h>
61 #else 61 #else
62 extern POINTER_TYPE *sbrk (); 62 extern POINTER_TYPE *sbrk ();
596 allocated_mem_type = type; 596 allocated_mem_type = type;
597 #endif 597 #endif
598 598
599 val = (void *) malloc (nbytes); 599 val = (void *) malloc (nbytes);
600 600
601 #ifndef USE_LSB_TAG
601 /* If the memory just allocated cannot be addressed thru a Lisp 602 /* If the memory just allocated cannot be addressed thru a Lisp
602 object's pointer, and it needs to be, 603 object's pointer, and it needs to be,
603 that's equivalent to running out of memory. */ 604 that's equivalent to running out of memory. */
604 if (val && type != MEM_TYPE_NON_LISP) 605 if (val && type != MEM_TYPE_NON_LISP)
605 { 606 {
610 lisp_malloc_loser = val; 611 lisp_malloc_loser = val;
611 free (val); 612 free (val);
612 val = 0; 613 val = 0;
613 } 614 }
614 } 615 }
616 #endif
615 617
616 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK 618 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
617 if (val && type != MEM_TYPE_NON_LISP) 619 if (val && type != MEM_TYPE_NON_LISP)
618 mem_insert (val, (char *) val + nbytes, type); 620 mem_insert (val, (char *) val + nbytes, type);
619 #endif 621 #endif
754 abase = err ? (base = NULL) : base; 756 abase = err ? (base = NULL) : base;
755 } 757 }
756 #else 758 #else
757 base = malloc (ABLOCKS_BYTES); 759 base = malloc (ABLOCKS_BYTES);
758 abase = ALIGN (base, BLOCK_ALIGN); 760 abase = ALIGN (base, BLOCK_ALIGN);
761 if (base == 0)
762 {
763 UNBLOCK_INPUT;
764 memory_full ();
765 }
759 #endif 766 #endif
760 767
761 aligned = (base == abase); 768 aligned = (base == abase);
762 if (!aligned) 769 if (!aligned)
763 ((void**)abase)[-1] = base; 770 ((void**)abase)[-1] = base;
765 #ifdef DOUG_LEA_MALLOC 772 #ifdef DOUG_LEA_MALLOC
766 /* Back to a reasonable maximum of mmap'ed areas. */ 773 /* Back to a reasonable maximum of mmap'ed areas. */
767 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 774 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
768 #endif 775 #endif
769 776
777 #ifndef USE_LSB_TAG
770 /* If the memory just allocated cannot be addressed thru a Lisp 778 /* If the memory just allocated cannot be addressed thru a Lisp
771 object's pointer, and it needs to be, that's equivalent to 779 object's pointer, and it needs to be, that's equivalent to
772 running out of memory. */ 780 running out of memory. */
773 if (type != MEM_TYPE_NON_LISP) 781 if (type != MEM_TYPE_NON_LISP)
774 { 782 {
781 free (base); 789 free (base);
782 UNBLOCK_INPUT; 790 UNBLOCK_INPUT;
783 memory_full (); 791 memory_full ();
784 } 792 }
785 } 793 }
794 #endif
786 795
787 /* Initialize the blocks and put them on the free list. 796 /* Initialize the blocks and put them on the free list.
788 Is `base' was not properly aligned, we can't use the last block. */ 797 Is `base' was not properly aligned, we can't use the last block. */
789 for (i = 0; i < (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1); i++) 798 for (i = 0; i < (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1); i++)
790 { 799 {
1097 /* Intervals are allocated in chunks in form of an interval_block 1106 /* Intervals are allocated in chunks in form of an interval_block
1098 structure. */ 1107 structure. */
1099 1108
1100 struct interval_block 1109 struct interval_block
1101 { 1110 {
1111 /* Place `intervals' first, to preserve alignment. */
1112 struct interval intervals[INTERVAL_BLOCK_SIZE];
1102 struct interval_block *next; 1113 struct interval_block *next;
1103 struct interval intervals[INTERVAL_BLOCK_SIZE];
1104 }; 1114 };
1105 1115
1106 /* Current interval block. Its `next' pointer points to older 1116 /* Current interval block. Its `next' pointer points to older
1107 blocks. */ 1117 blocks. */
1108 1118
1336 /* Structure describing a block from which Lisp_String structures 1346 /* Structure describing a block from which Lisp_String structures
1337 are allocated. */ 1347 are allocated. */
1338 1348
1339 struct string_block 1349 struct string_block
1340 { 1350 {
1351 /* Place `strings' first, to preserve alignment. */
1352 struct Lisp_String strings[STRING_BLOCK_SIZE];
1341 struct string_block *next; 1353 struct string_block *next;
1342 struct Lisp_String strings[STRING_BLOCK_SIZE];
1343 }; 1354 };
1344 1355
1345 /* Head and tail of the list of sblock structures holding Lisp string 1356 /* Head and tail of the list of sblock structures holding Lisp string
1346 data. We always allocate from current_sblock. The NEXT pointers 1357 data. We always allocate from current_sblock. The NEXT pointers
1347 in the sblock structures go from oldest_sblock to current_sblock. */ 1358 in the sblock structures go from oldest_sblock to current_sblock. */
2118 /* We store float cells inside of float_blocks, allocating a new 2129 /* We store float cells inside of float_blocks, allocating a new
2119 float_block with malloc whenever necessary. Float cells reclaimed 2130 float_block with malloc whenever necessary. Float cells reclaimed
2120 by GC are put on a free list to be reallocated before allocating 2131 by GC are put on a free list to be reallocated before allocating
2121 any new float cells from the latest float_block. */ 2132 any new float cells from the latest float_block. */
2122 2133
2123 #define FLOAT_BLOCK_SIZE \ 2134 #define FLOAT_BLOCK_SIZE \
2124 (((BLOCK_BYTES - sizeof (struct float_block *)) * CHAR_BIT) \ 2135 (((BLOCK_BYTES - sizeof (struct float_block *) \
2136 /* The compiler might add padding at the end. */ \
2137 - (sizeof (struct Lisp_Float) - sizeof (int))) * CHAR_BIT) \
2125 / (sizeof (struct Lisp_Float) * CHAR_BIT + 1)) 2138 / (sizeof (struct Lisp_Float) * CHAR_BIT + 1))
2126 2139
2127 #define GETMARKBIT(block,n) \ 2140 #define GETMARKBIT(block,n) \
2128 (((block)->gcmarkbits[(n) / (sizeof(int) * CHAR_BIT)] \ 2141 (((block)->gcmarkbits[(n) / (sizeof(int) * CHAR_BIT)] \
2129 >> ((n) % (sizeof(int) * CHAR_BIT))) \ 2142 >> ((n) % (sizeof(int) * CHAR_BIT))) \
2222 register struct float_block *new; 2235 register struct float_block *new;
2223 2236
2224 new = (struct float_block *) lisp_align_malloc (sizeof *new, 2237 new = (struct float_block *) lisp_align_malloc (sizeof *new,
2225 MEM_TYPE_FLOAT); 2238 MEM_TYPE_FLOAT);
2226 new->next = float_block; 2239 new->next = float_block;
2240 bzero ((char *) new->gcmarkbits, sizeof new->gcmarkbits);
2227 float_block = new; 2241 float_block = new;
2228 float_block_index = 0; 2242 float_block_index = 0;
2229 n_float_blocks++; 2243 n_float_blocks++;
2230 } 2244 }
2231 XSETFLOAT (val, &float_block->floats[float_block_index++]); 2245 XSETFLOAT (val, &float_block->floats[float_block_index]);
2246 float_block_index++;
2232 } 2247 }
2233 2248
2234 XFLOAT_DATA (val) = float_value; 2249 XFLOAT_DATA (val) = float_value;
2235 FLOAT_UNMARK (XFLOAT (val)); 2250 eassert (!FLOAT_MARKED_P (XFLOAT (val)));
2236 consing_since_gc += sizeof (struct Lisp_Float); 2251 consing_since_gc += sizeof (struct Lisp_Float);
2237 floats_consed++; 2252 floats_consed++;
2238 return val; 2253 return val;
2239 } 2254 }
2240 2255
2338 if (cons_block_index == CONS_BLOCK_SIZE) 2353 if (cons_block_index == CONS_BLOCK_SIZE)
2339 { 2354 {
2340 register struct cons_block *new; 2355 register struct cons_block *new;
2341 new = (struct cons_block *) lisp_align_malloc (sizeof *new, 2356 new = (struct cons_block *) lisp_align_malloc (sizeof *new,
2342 MEM_TYPE_CONS); 2357 MEM_TYPE_CONS);
2358 bzero ((char *) new->gcmarkbits, sizeof new->gcmarkbits);
2343 new->next = cons_block; 2359 new->next = cons_block;
2344 cons_block = new; 2360 cons_block = new;
2345 cons_block_index = 0; 2361 cons_block_index = 0;
2346 n_cons_blocks++; 2362 n_cons_blocks++;
2347 } 2363 }
2348 XSETCONS (val, &cons_block->conses[cons_block_index++]); 2364 XSETCONS (val, &cons_block->conses[cons_block_index]);
2365 cons_block_index++;
2349 } 2366 }
2350 2367
2351 XSETCAR (val, car); 2368 XSETCAR (val, car);
2352 XSETCDR (val, cdr); 2369 XSETCDR (val, cdr);
2353 CONS_UNMARK (XCONS (val)); 2370 eassert (!CONS_MARKED_P (XCONS (val)));
2354 consing_since_gc += sizeof (struct Lisp_Cons); 2371 consing_since_gc += sizeof (struct Lisp_Cons);
2355 cons_cells_consed++; 2372 cons_cells_consed++;
2356 return val; 2373 return val;
2357 } 2374 }
2358 2375
2487 2504
2488 #ifdef DOUG_LEA_MALLOC 2505 #ifdef DOUG_LEA_MALLOC
2489 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed 2506 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed
2490 because mapped region contents are not preserved in 2507 because mapped region contents are not preserved in
2491 a dumped Emacs. */ 2508 a dumped Emacs. */
2509 BLOCK_INPUT;
2492 mallopt (M_MMAP_MAX, 0); 2510 mallopt (M_MMAP_MAX, 0);
2511 UNBLOCK_INPUT;
2493 #endif 2512 #endif
2494 2513
2495 nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; 2514 nbytes = sizeof *p + (len - 1) * sizeof p->contents[0];
2496 p = (struct Lisp_Vector *) lisp_malloc (nbytes, type); 2515 p = (struct Lisp_Vector *) lisp_malloc (nbytes, type);
2497 2516
2498 #ifdef DOUG_LEA_MALLOC 2517 #ifdef DOUG_LEA_MALLOC
2499 /* Back to a reasonable maximum of mmap'ed areas. */ 2518 /* Back to a reasonable maximum of mmap'ed areas. */
2519 BLOCK_INPUT;
2500 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 2520 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
2521 UNBLOCK_INPUT;
2501 #endif 2522 #endif
2502 2523
2503 consing_since_gc += nbytes; 2524 consing_since_gc += nbytes;
2504 vector_cells_consed += len; 2525 vector_cells_consed += len;
2505 2526
2695 #define SYMBOL_BLOCK_SIZE \ 2716 #define SYMBOL_BLOCK_SIZE \
2696 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) 2717 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
2697 2718
2698 struct symbol_block 2719 struct symbol_block
2699 { 2720 {
2721 /* Place `symbols' first, to preserve alignment. */
2722 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
2700 struct symbol_block *next; 2723 struct symbol_block *next;
2701 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
2702 }; 2724 };
2703 2725
2704 /* Current symbol block and index of first unused Lisp_Symbol 2726 /* Current symbol block and index of first unused Lisp_Symbol
2705 structure in it. */ 2727 structure in it. */
2706 2728
2754 new->next = symbol_block; 2776 new->next = symbol_block;
2755 symbol_block = new; 2777 symbol_block = new;
2756 symbol_block_index = 0; 2778 symbol_block_index = 0;
2757 n_symbol_blocks++; 2779 n_symbol_blocks++;
2758 } 2780 }
2759 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index++]); 2781 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]);
2782 symbol_block_index++;
2760 } 2783 }
2761 2784
2762 p = XSYMBOL (val); 2785 p = XSYMBOL (val);
2763 p->xname = name; 2786 p->xname = name;
2764 p->plist = Qnil; 2787 p->plist = Qnil;
2786 #define MARKER_BLOCK_SIZE \ 2809 #define MARKER_BLOCK_SIZE \
2787 ((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc)) 2810 ((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc))
2788 2811
2789 struct marker_block 2812 struct marker_block
2790 { 2813 {
2814 /* Place `markers' first, to preserve alignment. */
2815 union Lisp_Misc markers[MARKER_BLOCK_SIZE];
2791 struct marker_block *next; 2816 struct marker_block *next;
2792 union Lisp_Misc markers[MARKER_BLOCK_SIZE];
2793 }; 2817 };
2794 2818
2795 struct marker_block *marker_block; 2819 struct marker_block *marker_block;
2796 int marker_block_index; 2820 int marker_block_index;
2797 2821
2832 new->next = marker_block; 2856 new->next = marker_block;
2833 marker_block = new; 2857 marker_block = new;
2834 marker_block_index = 0; 2858 marker_block_index = 0;
2835 n_marker_blocks++; 2859 n_marker_blocks++;
2836 } 2860 }
2837 XSETMISC (val, &marker_block->markers[marker_block_index++]); 2861 XSETMISC (val, &marker_block->markers[marker_block_index]);
2862 marker_block_index++;
2838 } 2863 }
2839 2864
2840 consing_since_gc += sizeof (union Lisp_Misc); 2865 consing_since_gc += sizeof (union Lisp_Misc);
2841 misc_objects_consed++; 2866 misc_objects_consed++;
2842 XMARKER (val)->gcmarkbit = 0; 2867 XMARKER (val)->gcmarkbit = 0;
3367 3392
3368 /* P must point to the start of a Lisp_String structure, and it 3393 /* P must point to the start of a Lisp_String structure, and it
3369 must not be on the free-list. */ 3394 must not be on the free-list. */
3370 return (offset >= 0 3395 return (offset >= 0
3371 && offset % sizeof b->strings[0] == 0 3396 && offset % sizeof b->strings[0] == 0
3397 && offset < (STRING_BLOCK_SIZE * sizeof b->strings[0])
3372 && ((struct Lisp_String *) p)->data != NULL); 3398 && ((struct Lisp_String *) p)->data != NULL);
3373 } 3399 }
3374 else 3400 else
3375 return 0; 3401 return 0;
3376 } 3402 }
3391 3417
3392 /* P must point to the start of a Lisp_Cons, not be 3418 /* P must point to the start of a Lisp_Cons, not be
3393 one of the unused cells in the current cons block, 3419 one of the unused cells in the current cons block,
3394 and not be on the free-list. */ 3420 and not be on the free-list. */
3395 return (offset >= 0 3421 return (offset >= 0
3422 && offset % sizeof b->conses[0] == 0
3396 && offset < (CONS_BLOCK_SIZE * sizeof b->conses[0]) 3423 && offset < (CONS_BLOCK_SIZE * sizeof b->conses[0])
3397 && offset % sizeof b->conses[0] == 0
3398 && (b != cons_block 3424 && (b != cons_block
3399 || offset / sizeof b->conses[0] < cons_block_index) 3425 || offset / sizeof b->conses[0] < cons_block_index)
3400 && !EQ (((struct Lisp_Cons *) p)->car, Vdead)); 3426 && !EQ (((struct Lisp_Cons *) p)->car, Vdead));
3401 } 3427 }
3402 else 3428 else
3420 /* P must point to the start of a Lisp_Symbol, not be 3446 /* P must point to the start of a Lisp_Symbol, not be
3421 one of the unused cells in the current symbol block, 3447 one of the unused cells in the current symbol block,
3422 and not be on the free-list. */ 3448 and not be on the free-list. */
3423 return (offset >= 0 3449 return (offset >= 0
3424 && offset % sizeof b->symbols[0] == 0 3450 && offset % sizeof b->symbols[0] == 0
3451 && offset < (SYMBOL_BLOCK_SIZE * sizeof b->symbols[0])
3425 && (b != symbol_block 3452 && (b != symbol_block
3426 || offset / sizeof b->symbols[0] < symbol_block_index) 3453 || offset / sizeof b->symbols[0] < symbol_block_index)
3427 && !EQ (((struct Lisp_Symbol *) p)->function, Vdead)); 3454 && !EQ (((struct Lisp_Symbol *) p)->function, Vdead));
3428 } 3455 }
3429 else 3456 else
3445 int offset = (char *) p - (char *) &b->floats[0]; 3472 int offset = (char *) p - (char *) &b->floats[0];
3446 3473
3447 /* P must point to the start of a Lisp_Float and not be 3474 /* P must point to the start of a Lisp_Float and not be
3448 one of the unused cells in the current float block. */ 3475 one of the unused cells in the current float block. */
3449 return (offset >= 0 3476 return (offset >= 0
3477 && offset % sizeof b->floats[0] == 0
3450 && offset < (FLOAT_BLOCK_SIZE * sizeof b->floats[0]) 3478 && offset < (FLOAT_BLOCK_SIZE * sizeof b->floats[0])
3451 && offset % sizeof b->floats[0] == 0
3452 && (b != float_block 3479 && (b != float_block
3453 || offset / sizeof b->floats[0] < float_block_index)); 3480 || offset / sizeof b->floats[0] < float_block_index));
3454 } 3481 }
3455 else 3482 else
3456 return 0; 3483 return 0;
3473 /* P must point to the start of a Lisp_Misc, not be 3500 /* P must point to the start of a Lisp_Misc, not be
3474 one of the unused cells in the current misc block, 3501 one of the unused cells in the current misc block,
3475 and not be on the free-list. */ 3502 and not be on the free-list. */
3476 return (offset >= 0 3503 return (offset >= 0
3477 && offset % sizeof b->markers[0] == 0 3504 && offset % sizeof b->markers[0] == 0
3505 && offset < (MARKER_BLOCK_SIZE * sizeof b->markers[0])
3478 && (b != marker_block 3506 && (b != marker_block
3479 || offset / sizeof b->markers[0] < marker_block_index) 3507 || offset / sizeof b->markers[0] < marker_block_index)
3480 && ((union Lisp_Misc *) p)->u_marker.type != Lisp_Misc_Free); 3508 && ((union Lisp_Misc *) p)->u_marker.type != Lisp_Misc_Free);
3481 } 3509 }
3482 else 3510 else
4007 pure_alloc (size, type) 4035 pure_alloc (size, type)
4008 size_t size; 4036 size_t size;
4009 int type; 4037 int type;
4010 { 4038 {
4011 POINTER_TYPE *result; 4039 POINTER_TYPE *result;
4040 #ifdef USE_LSB_TAG
4041 size_t alignment = (1 << GCTYPEBITS);
4042 #else
4012 size_t alignment = sizeof (EMACS_INT); 4043 size_t alignment = sizeof (EMACS_INT);
4013 4044
4014 /* Give Lisp_Floats an extra alignment. */ 4045 /* Give Lisp_Floats an extra alignment. */
4015 if (type == Lisp_Float) 4046 if (type == Lisp_Float)
4016 { 4047 {
4018 alignment = __alignof (struct Lisp_Float); 4049 alignment = __alignof (struct Lisp_Float);
4019 #else 4050 #else
4020 alignment = sizeof (struct Lisp_Float); 4051 alignment = sizeof (struct Lisp_Float);
4021 #endif 4052 #endif
4022 } 4053 }
4054 #endif
4023 4055
4024 again: 4056 again:
4025 result = ALIGN (purebeg + pure_bytes_used, alignment); 4057 result = ALIGN (purebeg + pure_bytes_used, alignment);
4026 pure_bytes_used = ((char *)result - (char *)purebeg) + size; 4058 pure_bytes_used = ((char *)result - (char *)purebeg) + size;
4027 4059
4153 SBYTES (obj), 4185 SBYTES (obj),
4154 STRING_MULTIBYTE (obj)); 4186 STRING_MULTIBYTE (obj));
4155 else if (COMPILEDP (obj) || VECTORP (obj)) 4187 else if (COMPILEDP (obj) || VECTORP (obj))
4156 { 4188 {
4157 register struct Lisp_Vector *vec; 4189 register struct Lisp_Vector *vec;
4158 register int i, size; 4190 register int i;
4191 EMACS_INT size;
4159 4192
4160 size = XVECTOR (obj)->size; 4193 size = XVECTOR (obj)->size;
4161 if (size & PSEUDOVECTOR_FLAG) 4194 if (size & PSEUDOVECTOR_FLAG)
4162 size &= PSEUDOVECTOR_SIZE_MASK; 4195 size &= PSEUDOVECTOR_SIZE_MASK;
4163 vec = XVECTOR (make_pure_vector ((EMACS_INT) size)); 4196 vec = XVECTOR (make_pure_vector (size));
4164 for (i = 0; i < size; i++) 4197 for (i = 0; i < size; i++)
4165 vec->contents[i] = Fpurecopy (XVECTOR (obj)->contents[i]); 4198 vec->contents[i] = Fpurecopy (XVECTOR (obj)->contents[i]);
4166 if (COMPILEDP (obj)) 4199 if (COMPILEDP (obj))
4167 XSETCOMPILED (obj, vec); 4200 XSETCOMPILED (obj, vec);
4168 else 4201 else
4443 #endif 4476 #endif
4444 4477
4445 gc_sweep (); 4478 gc_sweep ();
4446 4479
4447 /* Clear the mark bits that we set in certain root slots. */ 4480 /* Clear the mark bits that we set in certain root slots. */
4448
4449 #if (GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE \
4450 || GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES)
4451 {
4452 register struct gcpro *tail;
4453 }
4454 #endif
4455 4481
4456 unmark_byte_stack (); 4482 unmark_byte_stack ();
4457 VECTOR_UNMARK (&buffer_defaults); 4483 VECTOR_UNMARK (&buffer_defaults);
4458 VECTOR_UNMARK (&buffer_local_symbols); 4484 VECTOR_UNMARK (&buffer_local_symbols);
4459 4485