aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorJoakim Verona2012-06-13 18:00:21 +0200
committerJoakim Verona2012-06-13 18:00:21 +0200
commit13d6898b0656b38da837261ec20a055a1be4a7e5 (patch)
treeb3399abf9cbea221b083b5bd8368915169b02fb1 /src/alloc.c
parent5259b41aab32e82ff06d977877f2e456541b3c0b (diff)
parent8cca97031d60136b3bdebef0d978ee3fe40eddec (diff)
downloademacs-13d6898b0656b38da837261ec20a055a1be4a7e5.tar.gz
emacs-13d6898b0656b38da837261ec20a055a1be4a7e5.zip
upstream, doesn build yet
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c499
1 files changed, 388 insertions, 111 deletions
diff --git a/src/alloc.c b/src/alloc.c
index cf7778c05f6..1478ce9ae4e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -304,7 +304,9 @@ enum mem_type
304 process, hash_table, frame, terminal, and window, but we never made 304 process, hash_table, frame, terminal, and window, but we never made
305 use of the distinction, so it only caused source-code complexity 305 use of the distinction, so it only caused source-code complexity
306 and runtime slowdown. Minor but pointless. */ 306 and runtime slowdown. Minor but pointless. */
307 MEM_TYPE_VECTORLIKE 307 MEM_TYPE_VECTORLIKE,
308 /* Special type to denote vector blocks. */
309 MEM_TYPE_VECTOR_BLOCK
308}; 310};
309 311
310static void *lisp_malloc (size_t, enum mem_type); 312static void *lisp_malloc (size_t, enum mem_type);
@@ -494,6 +496,11 @@ buffer_memory_full (ptrdiff_t nbytes)
494 xsignal (Qnil, Vmemory_signal_data); 496 xsignal (Qnil, Vmemory_signal_data);
495} 497}
496 498
499/* A common multiple of the positive integers A and B. Ideally this
500 would be the least common multiple, but there's no way to do that
501 as a constant expression in C, so do the best that we can easily do. */
502#define COMMON_MULTIPLE(a, b) \
503 ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
497 504
498#ifndef XMALLOC_OVERRUN_CHECK 505#ifndef XMALLOC_OVERRUN_CHECK
499#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 506#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
@@ -525,12 +532,8 @@ buffer_memory_full (ptrdiff_t nbytes)
525 char c; \ 532 char c; \
526 }, \ 533 }, \
527 c) 534 c)
528#ifdef USE_LSB_TAG 535
529/* A common multiple of the positive integers A and B. Ideally this 536#if USE_LSB_TAG
530 would be the least common multiple, but there's no way to do that
531 as a constant expression in C, so do the best that we can easily do. */
532# define COMMON_MULTIPLE(a, b) \
533 ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
534# define XMALLOC_HEADER_ALIGNMENT \ 537# define XMALLOC_HEADER_ALIGNMENT \
535 COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) 538 COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT)
536#else 539#else
@@ -890,8 +893,8 @@ safe_alloca_unwind (Lisp_Object arg)
890 number of bytes to allocate, TYPE describes the intended use of the 893 number of bytes to allocate, TYPE describes the intended use of the
891 allocated memory block (for strings, for conses, ...). */ 894 allocated memory block (for strings, for conses, ...). */
892 895
893#ifndef USE_LSB_TAG 896#if ! USE_LSB_TAG
894static void *lisp_malloc_loser; 897void *lisp_malloc_loser EXTERNALLY_VISIBLE;
895#endif 898#endif
896 899
897static void * 900static void *
@@ -907,7 +910,7 @@ lisp_malloc (size_t nbytes, enum mem_type type)
907 910
908 val = (void *) malloc (nbytes); 911 val = (void *) malloc (nbytes);
909 912
910#ifndef USE_LSB_TAG 913#if ! USE_LSB_TAG
911 /* If the memory just allocated cannot be addressed thru a Lisp 914 /* If the memory just allocated cannot be addressed thru a Lisp
912 object's pointer, and it needs to be, 915 object's pointer, and it needs to be,
913 that's equivalent to running out of memory. */ 916 that's equivalent to running out of memory. */
@@ -1088,7 +1091,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1088 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 1091 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
1089#endif 1092#endif
1090 1093
1091#ifndef USE_LSB_TAG 1094#if ! USE_LSB_TAG
1092 /* If the memory just allocated cannot be addressed thru a Lisp 1095 /* If the memory just allocated cannot be addressed thru a Lisp
1093 object's pointer, and it needs to be, that's equivalent to 1096 object's pointer, and it needs to be, that's equivalent to
1094 running out of memory. */ 1097 running out of memory. */
@@ -1581,35 +1584,6 @@ mark_interval_tree (register INTERVAL tree)
1581 if (! NULL_INTERVAL_P (i)) \ 1584 if (! NULL_INTERVAL_P (i)) \
1582 (i) = balance_intervals (i); \ 1585 (i) = balance_intervals (i); \
1583 } while (0) 1586 } while (0)
1584
1585
1586/* Number support. If USE_LISP_UNION_TYPE is in effect, we
1587 can't create number objects in macros. */
1588#ifndef make_number
1589Lisp_Object
1590make_number (EMACS_INT n)
1591{
1592 Lisp_Object obj;
1593 obj.s.val = n;
1594 obj.s.type = Lisp_Int;
1595 return obj;
1596}
1597#endif
1598
1599/* Convert the pointer-sized word P to EMACS_INT while preserving its
1600 type and ptr fields. */
1601static Lisp_Object
1602widen_to_Lisp_Object (void *p)
1603{
1604 intptr_t i = (intptr_t) p;
1605#ifdef USE_LISP_UNION_TYPE
1606 Lisp_Object obj;
1607 obj.i = i;
1608 return obj;
1609#else
1610 return i;
1611#endif
1612}
1613 1587
1614/*********************************************************************** 1588/***********************************************************************
1615 String Allocation 1589 String Allocation
@@ -2701,8 +2675,10 @@ make_float (double float_value)
2701 GC are put on a free list to be reallocated before allocating 2675 GC are put on a free list to be reallocated before allocating
2702 any new cons cells from the latest cons_block. */ 2676 any new cons cells from the latest cons_block. */
2703 2677
2704#define CONS_BLOCK_SIZE \ 2678#define CONS_BLOCK_SIZE \
2705 (((BLOCK_BYTES - sizeof (struct cons_block *)) * CHAR_BIT) \ 2679 (((BLOCK_BYTES - sizeof (struct cons_block *) \
2680 /* The compiler might add padding at the end. */ \
2681 - (sizeof (struct Lisp_Cons) - sizeof (int))) * CHAR_BIT) \
2706 / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) 2682 / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1))
2707 2683
2708#define CONS_BLOCK(fptr) \ 2684#define CONS_BLOCK(fptr) \
@@ -2926,17 +2902,302 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2926 Vector Allocation 2902 Vector Allocation
2927 ***********************************************************************/ 2903 ***********************************************************************/
2928 2904
2929/* Singly-linked list of all vectors. */ 2905/* This value is balanced well enough to avoid too much internal overhead
2906 for the most common cases; it's not required to be a power of two, but
2907 it's expected to be a mult-of-ROUNDUP_SIZE (see below). */
2930 2908
2931static struct Lisp_Vector *all_vectors; 2909#define VECTOR_BLOCK_SIZE 4096
2932 2910
2933/* Handy constants for vectorlike objects. */ 2911/* Handy constants for vectorlike objects. */
2934enum 2912enum
2935 { 2913 {
2936 header_size = offsetof (struct Lisp_Vector, contents), 2914 header_size = offsetof (struct Lisp_Vector, contents),
2937 word_size = sizeof (Lisp_Object) 2915 word_size = sizeof (Lisp_Object),
2916 roundup_size = COMMON_MULTIPLE (sizeof (Lisp_Object),
2917 USE_LSB_TAG ? 1 << GCTYPEBITS : 1)
2938 }; 2918 };
2939 2919
2920/* ROUNDUP_SIZE must be a power of 2. */
2921verify ((roundup_size & (roundup_size - 1)) == 0);
2922
2923/* Round up X to nearest mult-of-ROUNDUP_SIZE. */
2924
2925#define vroundup(x) (((x) + (roundup_size - 1)) & ~(roundup_size - 1))
2926
2927/* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */
2928
2929#define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup (sizeof (void *)))
2930
2931/* Size of the minimal vector allocated from block. */
2932
2933#define VBLOCK_BYTES_MIN vroundup (sizeof (struct Lisp_Vector))
2934
2935/* Size of the largest vector allocated from block. */
2936
2937#define VBLOCK_BYTES_MAX \
2938 vroundup ((VECTOR_BLOCK_BYTES / 2) - sizeof (Lisp_Object))
2939
2940/* We maintain one free list for each possible block-allocated
2941 vector size, and this is the number of free lists we have. */
2942
2943#define VECTOR_MAX_FREE_LIST_INDEX \
2944 ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1)
2945
2946/* When the vector is on a free list, vectorlike_header.SIZE is set to
2947 this special value ORed with vector's memory footprint size. */
2948
2949#define VECTOR_FREE_LIST_FLAG (~(ARRAY_MARK_FLAG | PSEUDOVECTOR_FLAG \
2950 | (VECTOR_BLOCK_SIZE - 1)))
2951
2952/* Common shortcut to advance vector pointer over a block data. */
2953
2954#define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes)))
2955
2956/* Common shortcut to calculate NBYTES-vector index in VECTOR_FREE_LISTS. */
2957
2958#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2959
2960/* Common shortcut to setup vector on a free list. */
2961
2962#define SETUP_ON_FREE_LIST(v, nbytes, index) \
2963 do { \
2964 (v)->header.size = VECTOR_FREE_LIST_FLAG | (nbytes); \
2965 eassert ((nbytes) % roundup_size == 0); \
2966 (index) = VINDEX (nbytes); \
2967 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \
2968 (v)->header.next.vector = vector_free_lists[index]; \
2969 vector_free_lists[index] = (v); \
2970 } while (0)
2971
2972struct vector_block
2973{
2974 char data[VECTOR_BLOCK_BYTES];
2975 struct vector_block *next;
2976};
2977
2978/* Chain of vector blocks. */
2979
2980static struct vector_block *vector_blocks;
2981
2982/* Vector free lists, where NTH item points to a chain of free
2983 vectors of the same NBYTES size, so NTH == VINDEX (NBYTES). */
2984
2985static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX];
2986
2987/* Singly-linked list of large vectors. */
2988
2989static struct Lisp_Vector *large_vectors;
2990
2991/* The only vector with 0 slots, allocated from pure space. */
2992
2993static struct Lisp_Vector *zero_vector;
2994
2995/* Get a new vector block. */
2996
2997static struct vector_block *
2998allocate_vector_block (void)
2999{
3000 struct vector_block *block;
3001
3002#ifdef DOUG_LEA_MALLOC
3003 mallopt (M_MMAP_MAX, 0);
3004#endif
3005
3006 block = xmalloc (sizeof (struct vector_block));
3007
3008#ifdef DOUG_LEA_MALLOC
3009 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
3010#endif
3011
3012#if GC_MARK_STACK && !defined GC_MALLOC_CHECK
3013 mem_insert (block->data, block->data + VECTOR_BLOCK_BYTES,
3014 MEM_TYPE_VECTOR_BLOCK);
3015#endif
3016
3017 block->next = vector_blocks;
3018 vector_blocks = block;
3019 return block;
3020}
3021
3022/* Called once to initialize vector allocation. */
3023
3024static void
3025init_vectors (void)
3026{
3027 zero_vector = pure_alloc (header_size, Lisp_Vectorlike);
3028 zero_vector->header.size = 0;
3029}
3030
3031/* Allocate vector from a vector block. */
3032
3033static struct Lisp_Vector *
3034allocate_vector_from_block (size_t nbytes)
3035{
3036 struct Lisp_Vector *vector, *rest;
3037 struct vector_block *block;
3038 size_t index, restbytes;
3039
3040 eassert (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX);
3041 eassert (nbytes % roundup_size == 0);
3042
3043 /* First, try to allocate from a free list
3044 containing vectors of the requested size. */
3045 index = VINDEX (nbytes);
3046 if (vector_free_lists[index])
3047 {
3048 vector = vector_free_lists[index];
3049 vector_free_lists[index] = vector->header.next.vector;
3050 vector->header.next.nbytes = nbytes;
3051 return vector;
3052 }
3053
3054 /* Next, check free lists containing larger vectors. Since
3055 we will split the result, we should have remaining space
3056 large enough to use for one-slot vector at least. */
3057 for (index = VINDEX (nbytes + VBLOCK_BYTES_MIN);
3058 index < VECTOR_MAX_FREE_LIST_INDEX; index++)
3059 if (vector_free_lists[index])
3060 {
3061 /* This vector is larger than requested. */
3062 vector = vector_free_lists[index];
3063 vector_free_lists[index] = vector->header.next.vector;
3064 vector->header.next.nbytes = nbytes;
3065
3066 /* Excess bytes are used for the smaller vector,
3067 which should be set on an appropriate free list. */
3068 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes;
3069 eassert (restbytes % roundup_size == 0);
3070 rest = ADVANCE (vector, nbytes);
3071 SETUP_ON_FREE_LIST (rest, restbytes, index);
3072 return vector;
3073 }
3074
3075 /* Finally, need a new vector block. */
3076 block = allocate_vector_block ();
3077
3078 /* New vector will be at the beginning of this block. */
3079 vector = (struct Lisp_Vector *) block->data;
3080 vector->header.next.nbytes = nbytes;
3081
3082 /* If the rest of space from this block is large enough
3083 for one-slot vector at least, set up it on a free list. */
3084 restbytes = VECTOR_BLOCK_BYTES - nbytes;
3085 if (restbytes >= VBLOCK_BYTES_MIN)
3086 {
3087 eassert (restbytes % roundup_size == 0);
3088 rest = ADVANCE (vector, nbytes);
3089 SETUP_ON_FREE_LIST (rest, restbytes, index);
3090 }
3091 return vector;
3092 }
3093
3094/* Return how many Lisp_Objects can be stored in V. */
3095
3096#define VECTOR_SIZE(v) ((v)->header.size & PSEUDOVECTOR_FLAG ? \
3097 (PSEUDOVECTOR_SIZE_MASK & (v)->header.size) : \
3098 (v)->header.size)
3099
3100/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
3101
3102#define VECTOR_IN_BLOCK(vector, block) \
3103 ((char *) (vector) <= (block)->data \
3104 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN)
3105
3106/* Reclaim space used by unmarked vectors. */
3107
3108static void
3109sweep_vectors (void)
3110{
3111 struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
3112 struct Lisp_Vector *vector, *next, **vprev = &large_vectors;
3113
3114 total_vector_size = 0;
3115 memset (vector_free_lists, 0, sizeof (vector_free_lists));
3116
3117 /* Looking through vector blocks. */
3118
3119 for (block = vector_blocks; block; block = *bprev)
3120 {
3121 int free_this_block = 0;
3122
3123 for (vector = (struct Lisp_Vector *) block->data;
3124 VECTOR_IN_BLOCK (vector, block); vector = next)
3125 {
3126 if (VECTOR_MARKED_P (vector))
3127 {
3128 VECTOR_UNMARK (vector);
3129 total_vector_size += VECTOR_SIZE (vector);
3130 next = ADVANCE (vector, vector->header.next.nbytes);
3131 }
3132 else
3133 {
3134 ptrdiff_t nbytes;
3135
3136 if ((vector->header.size & VECTOR_FREE_LIST_FLAG)
3137 == VECTOR_FREE_LIST_FLAG)
3138 vector->header.next.nbytes =
3139 vector->header.size & (VECTOR_BLOCK_SIZE - 1);
3140
3141 next = ADVANCE (vector, vector->header.next.nbytes);
3142
3143 /* While NEXT is not marked, try to coalesce with VECTOR,
3144 thus making VECTOR of the largest possible size. */
3145
3146 while (VECTOR_IN_BLOCK (next, block))
3147 {
3148 if (VECTOR_MARKED_P (next))
3149 break;
3150 if ((next->header.size & VECTOR_FREE_LIST_FLAG)
3151 == VECTOR_FREE_LIST_FLAG)
3152 nbytes = next->header.size & (VECTOR_BLOCK_SIZE - 1);
3153 else
3154 nbytes = next->header.next.nbytes;
3155 vector->header.next.nbytes += nbytes;
3156 next = ADVANCE (next, nbytes);
3157 }
3158
3159 eassert (vector->header.next.nbytes % roundup_size == 0);
3160
3161 if (vector == (struct Lisp_Vector *) block->data
3162 && !VECTOR_IN_BLOCK (next, block))
3163 /* This block should be freed because all of it's
3164 space was coalesced into the only free vector. */
3165 free_this_block = 1;
3166 else
3167 SETUP_ON_FREE_LIST (vector, vector->header.next.nbytes, nbytes);
3168 }
3169 }
3170
3171 if (free_this_block)
3172 {
3173 *bprev = block->next;
3174#if GC_MARK_STACK && !defined GC_MALLOC_CHECK
3175 mem_delete (mem_find (block->data));
3176#endif
3177 xfree (block);
3178 }
3179 else
3180 bprev = &block->next;
3181 }
3182
3183 /* Sweep large vectors. */
3184
3185 for (vector = large_vectors; vector; vector = *vprev)
3186 {
3187 if (VECTOR_MARKED_P (vector))
3188 {
3189 VECTOR_UNMARK (vector);
3190 total_vector_size += VECTOR_SIZE (vector);
3191 vprev = &vector->header.next.vector;
3192 }
3193 else
3194 {
3195 *vprev = vector->header.next.vector;
3196 lisp_free (vector);
3197 }
3198 }
3199}
3200
2940/* Value is a pointer to a newly allocated Lisp_Vector structure 3201/* Value is a pointer to a newly allocated Lisp_Vector structure
2941 with room for LEN Lisp_Objects. */ 3202 with room for LEN Lisp_Objects. */
2942 3203
@@ -2958,8 +3219,22 @@ allocate_vectorlike (ptrdiff_t len)
2958 /* This gets triggered by code which I haven't bothered to fix. --Stef */ 3219 /* This gets triggered by code which I haven't bothered to fix. --Stef */
2959 /* eassert (!handling_signal); */ 3220 /* eassert (!handling_signal); */
2960 3221
3222 if (len == 0)
3223 {
3224 MALLOC_UNBLOCK_INPUT;
3225 return zero_vector;
3226 }
3227
2961 nbytes = header_size + len * word_size; 3228 nbytes = header_size + len * word_size;
2962 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); 3229
3230 if (nbytes <= VBLOCK_BYTES_MAX)
3231 p = allocate_vector_from_block (vroundup (nbytes));
3232 else
3233 {
3234 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE);
3235 p->header.next.vector = large_vectors;
3236 large_vectors = p;
3237 }
2963 3238
2964#ifdef DOUG_LEA_MALLOC 3239#ifdef DOUG_LEA_MALLOC
2965 /* Back to a reasonable maximum of mmap'ed areas. */ 3240 /* Back to a reasonable maximum of mmap'ed areas. */
@@ -2969,9 +3244,6 @@ allocate_vectorlike (ptrdiff_t len)
2969 consing_since_gc += nbytes; 3244 consing_since_gc += nbytes;
2970 vector_cells_consed += len; 3245 vector_cells_consed += len;
2971 3246
2972 p->header.next.vector = all_vectors;
2973 all_vectors = p;
2974
2975 MALLOC_UNBLOCK_INPUT; 3247 MALLOC_UNBLOCK_INPUT;
2976 3248
2977 return p; 3249 return p;
@@ -3095,6 +3367,19 @@ usage: (vector &rest OBJECTS) */)
3095 return val; 3367 return val;
3096} 3368}
3097 3369
3370void
3371make_byte_code (struct Lisp_Vector *v)
3372{
3373 if (v->header.size > 1 && STRINGP (v->contents[1])
3374 && STRING_MULTIBYTE (v->contents[1]))
3375 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
3376 earlier because they produced a raw 8-bit string for byte-code
3377 and now such a byte-code string is loaded as multibyte while
3378 raw 8-bit characters converted to multibyte form. Thus, now we
3379 must convert them back to the original unibyte form. */
3380 v->contents[1] = Fstring_as_unibyte (v->contents[1]);
3381 XSETPVECTYPE (v, PVEC_COMPILED);
3382}
3098 3383
3099DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, 3384DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0,
3100 doc: /* Create a byte-code object with specified arguments as elements. 3385 doc: /* Create a byte-code object with specified arguments as elements.
@@ -3118,28 +3403,21 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3118 ptrdiff_t i; 3403 ptrdiff_t i;
3119 register struct Lisp_Vector *p; 3404 register struct Lisp_Vector *p;
3120 3405
3121 XSETFASTINT (len, nargs); 3406 /* We used to purecopy everything here, if purify-flga was set. This worked
3122 if (!NILP (Vpurify_flag)) 3407 OK for Emacs-23, but with Emacs-24's lexical binding code, it can be
3123 val = make_pure_vector (nargs); 3408 dangerous, since make-byte-code is used during execution to build
3124 else 3409 closures, so any closure built during the preload phase would end up
3125 val = Fmake_vector (len, Qnil); 3410 copied into pure space, including its free variables, which is sometimes
3411 just wasteful and other times plainly wrong (e.g. those free vars may want
3412 to be setcar'd). */
3126 3413
3127 if (nargs > 1 && STRINGP (args[1]) && STRING_MULTIBYTE (args[1])) 3414 XSETFASTINT (len, nargs);
3128 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the 3415 val = Fmake_vector (len, Qnil);
3129 earlier because they produced a raw 8-bit string for byte-code
3130 and now such a byte-code string is loaded as multibyte while
3131 raw 8-bit characters converted to multibyte form. Thus, now we
3132 must convert them back to the original unibyte form. */
3133 args[1] = Fstring_as_unibyte (args[1]);
3134 3416
3135 p = XVECTOR (val); 3417 p = XVECTOR (val);
3136 for (i = 0; i < nargs; i++) 3418 for (i = 0; i < nargs; i++)
3137 { 3419 p->contents[i] = args[i];
3138 if (!NILP (Vpurify_flag)) 3420 make_byte_code (p);
3139 args[i] = Fpurecopy (args[i]);
3140 p->contents[i] = args[i];
3141 }
3142 XSETPVECTYPE (p, PVEC_COMPILED);
3143 XSETCOMPILED (val, p); 3421 XSETCOMPILED (val, p);
3144 return val; 3422 return val;
3145} 3423}
@@ -3156,7 +3434,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3156union aligned_Lisp_Symbol 3434union aligned_Lisp_Symbol
3157{ 3435{
3158 struct Lisp_Symbol s; 3436 struct Lisp_Symbol s;
3159#ifdef USE_LSB_TAG 3437#if USE_LSB_TAG
3160 unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) 3438 unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1)
3161 & -(1 << GCTYPEBITS)]; 3439 & -(1 << GCTYPEBITS)];
3162#endif 3440#endif
@@ -3164,7 +3442,7 @@ union aligned_Lisp_Symbol
3164 3442
3165/* Each symbol_block is just under 1020 bytes long, since malloc 3443/* Each symbol_block is just under 1020 bytes long, since malloc
3166 really allocates in units of powers of two and uses 4 bytes for its 3444 really allocates in units of powers of two and uses 4 bytes for its
3167 own overhead. */ 3445 own overhead. */
3168 3446
3169#define SYMBOL_BLOCK_SIZE \ 3447#define SYMBOL_BLOCK_SIZE \
3170 ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) 3448 ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol))
@@ -3262,7 +3540,7 @@ Its value and function definition are void, and its property list is nil. */)
3262union aligned_Lisp_Misc 3540union aligned_Lisp_Misc
3263{ 3541{
3264 union Lisp_Misc m; 3542 union Lisp_Misc m;
3265#ifdef USE_LSB_TAG 3543#if USE_LSB_TAG
3266 unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) 3544 unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1)
3267 & -(1 << GCTYPEBITS)]; 3545 & -(1 << GCTYPEBITS)];
3268#endif 3546#endif
@@ -4070,7 +4348,34 @@ live_misc_p (struct mem_node *m, void *p)
4070static inline int 4348static inline int
4071live_vector_p (struct mem_node *m, void *p) 4349live_vector_p (struct mem_node *m, void *p)
4072{ 4350{
4073 return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); 4351 if (m->type == MEM_TYPE_VECTOR_BLOCK)
4352 {
4353 /* This memory node corresponds to a vector block. */
4354 struct vector_block *block = (struct vector_block *) m->start;
4355 struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data;
4356
4357 /* P is in the block's allocation range. Scan the block
4358 up to P and see whether P points to the start of some
4359 vector which is not on a free list. FIXME: check whether
4360 some allocation patterns (probably a lot of short vectors)
4361 may cause a substantial overhead of this loop. */
4362 while (VECTOR_IN_BLOCK (vector, block)
4363 && vector <= (struct Lisp_Vector *) p)
4364 {
4365 if ((vector->header.size & VECTOR_FREE_LIST_FLAG)
4366 == VECTOR_FREE_LIST_FLAG)
4367 vector = ADVANCE (vector, (vector->header.size
4368 & (VECTOR_BLOCK_SIZE - 1)));
4369 else if (vector == p)
4370 return 1;
4371 else
4372 vector = ADVANCE (vector, vector->header.next.nbytes);
4373 }
4374 }
4375 else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start)
4376 /* This memory node corresponds to a large vector. */
4377 return 1;
4378 return 0;
4074} 4379}
4075 4380
4076 4381
@@ -4217,14 +4522,10 @@ mark_maybe_pointer (void *p)
4217{ 4522{
4218 struct mem_node *m; 4523 struct mem_node *m;
4219 4524
4220 /* Quickly rule out some values which can't point to Lisp data. */ 4525 /* Quickly rule out some values which can't point to Lisp data.
4221 if ((intptr_t) p % 4526 USE_LSB_TAG needs Lisp data to be aligned on multiples of 1 << GCTYPEBITS.
4222#ifdef USE_LSB_TAG 4527 Otherwise, assume that Lisp data is aligned on even addresses. */
4223 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ 4528 if ((intptr_t) p % (USE_LSB_TAG ? 1 << GCTYPEBITS : 2))
4224#else
4225 2 /* We assume that Lisp data is aligned on even addresses. */
4226#endif
4227 )
4228 return; 4529 return;
4229 4530
4230 m = mem_find (p); 4531 m = mem_find (p);
@@ -4270,6 +4571,7 @@ mark_maybe_pointer (void *p)
4270 break; 4571 break;
4271 4572
4272 case MEM_TYPE_VECTORLIKE: 4573 case MEM_TYPE_VECTORLIKE:
4574 case MEM_TYPE_VECTOR_BLOCK:
4273 if (live_vector_p (m, p)) 4575 if (live_vector_p (m, p))
4274 { 4576 {
4275 Lisp_Object tem; 4577 Lisp_Object tem;
@@ -4299,8 +4601,8 @@ mark_maybe_pointer (void *p)
4299 wider than a pointer might allocate a Lisp_Object in non-adjacent halves. 4601 wider than a pointer might allocate a Lisp_Object in non-adjacent halves.
4300 If USE_LSB_TAG, the bottom half is not a valid pointer, but it should 4602 If USE_LSB_TAG, the bottom half is not a valid pointer, but it should
4301 suffice to widen it to to a Lisp_Object and check it that way. */ 4603 suffice to widen it to to a Lisp_Object and check it that way. */
4302#if defined USE_LSB_TAG || VAL_MAX < UINTPTR_MAX 4604#if USE_LSB_TAG || VAL_MAX < UINTPTR_MAX
4303# if !defined USE_LSB_TAG && VAL_MAX < UINTPTR_MAX >> GCTYPEBITS 4605# if !USE_LSB_TAG && VAL_MAX < UINTPTR_MAX >> GCTYPEBITS
4304 /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer 4606 /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer
4305 nor mark_maybe_object can follow the pointers. This should not occur on 4607 nor mark_maybe_object can follow the pointers. This should not occur on
4306 any practical porting target. */ 4608 any practical porting target. */
@@ -4361,7 +4663,7 @@ mark_memory (void *start, void *end)
4361 void *p = *(void **) ((char *) pp + i); 4663 void *p = *(void **) ((char *) pp + i);
4362 mark_maybe_pointer (p); 4664 mark_maybe_pointer (p);
4363 if (POINTERS_MIGHT_HIDE_IN_OBJECTS) 4665 if (POINTERS_MIGHT_HIDE_IN_OBJECTS)
4364 mark_maybe_object (widen_to_Lisp_Object (p)); 4666 mark_maybe_object (XIL ((intptr_t) p));
4365 } 4667 }
4366} 4668}
4367 4669
@@ -4703,6 +5005,7 @@ valid_lisp_object_p (Lisp_Object obj)
4703 return live_float_p (m, p); 5005 return live_float_p (m, p);
4704 5006
4705 case MEM_TYPE_VECTORLIKE: 5007 case MEM_TYPE_VECTORLIKE:
5008 case MEM_TYPE_VECTOR_BLOCK:
4706 return live_vector_p (m, p); 5009 return live_vector_p (m, p);
4707 5010
4708 default: 5011 default:
@@ -4728,7 +5031,7 @@ static void *
4728pure_alloc (size_t size, int type) 5031pure_alloc (size_t size, int type)
4729{ 5032{
4730 void *result; 5033 void *result;
4731#ifdef USE_LSB_TAG 5034#if USE_LSB_TAG
4732 size_t alignment = (1 << GCTYPEBITS); 5035 size_t alignment = (1 << GCTYPEBITS);
4733#else 5036#else
4734 size_t alignment = sizeof (EMACS_INT); 5037 size_t alignment = sizeof (EMACS_INT);
@@ -6239,33 +6542,7 @@ gc_sweep (void)
6239 } 6542 }
6240 } 6543 }
6241 6544
6242 /* Free all unmarked vectors */ 6545 sweep_vectors ();
6243 {
6244 register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next;
6245 total_vector_size = 0;
6246
6247 while (vector)
6248 if (!VECTOR_MARKED_P (vector))
6249 {
6250 if (prev)
6251 prev->header.next = vector->header.next;
6252 else
6253 all_vectors = vector->header.next.vector;
6254 next = vector->header.next.vector;
6255 lisp_free (vector);
6256 vector = next;
6257
6258 }
6259 else
6260 {
6261 VECTOR_UNMARK (vector);
6262 if (vector->header.size & PSEUDOVECTOR_FLAG)
6263 total_vector_size += PSEUDOVECTOR_SIZE_MASK & vector->header.size;
6264 else
6265 total_vector_size += vector->header.size;
6266 prev = vector, vector = vector->header.next.vector;
6267 }
6268 }
6269 6546
6270#ifdef GC_CHECK_STRING_BYTES 6547#ifdef GC_CHECK_STRING_BYTES
6271 if (!noninteractive) 6548 if (!noninteractive)
@@ -6402,7 +6679,6 @@ init_alloc_once (void)
6402 Vdead = make_pure_string ("DEAD", 4, 4, 0); 6679 Vdead = make_pure_string ("DEAD", 4, 4, 0);
6403#endif 6680#endif
6404 6681
6405 all_vectors = 0;
6406 ignore_warnings = 1; 6682 ignore_warnings = 1;
6407#ifdef DOUG_LEA_MALLOC 6683#ifdef DOUG_LEA_MALLOC
6408 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ 6684 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */
@@ -6415,6 +6691,7 @@ init_alloc_once (void)
6415 init_marker (); 6691 init_marker ();
6416 init_float (); 6692 init_float ();
6417 init_intervals (); 6693 init_intervals ();
6694 init_vectors ();
6418 init_weak_hash_tables (); 6695 init_weak_hash_tables ();
6419 6696
6420#ifdef REL_ALLOC 6697#ifdef REL_ALLOC