aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-07-18 10:26:43 -0700
committerPaul Eggert2012-07-18 10:26:43 -0700
commitd06714cb449d3eb3f58f4ed79053ca173db286fa (patch)
treef84b9eb183e4ac255840eb721747da7238fd9cb1 /src
parent5fbc0409ac3c51baf18d43b00ed00b56acc1c74b (diff)
downloademacs-d06714cb449d3eb3f58f4ed79053ca173db286fa.tar.gz
emacs-d06714cb449d3eb3f58f4ed79053ca173db286fa.zip
Remove some struct layout assumptions in bool vectors.
* alloc.c (bool_header_size): New constant. (header_size, word_size): Move earlier, as they're now used earlier. Use 'word_size' in a few more places, where it's appropriate. (Fmake_bool_vector, sweep_vectors): Don't assume that there is no padding before the data member of a bool vector. (sweep_vectors): Use PSEUDOVECTOR_TYPEP, in an eassert, rather than doing the check by hand with an abort ().
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/alloc.c55
2 files changed, 39 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b7e6b5b5fce..3f12159d169 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12012-07-18 Paul Eggert <eggert@cs.ucla.edu>
2
3 Remove some struct layout assumptions in bool vectors.
4 * alloc.c (bool_header_size): New constant.
5 (header_size, word_size): Move earlier, as they're now used earlier.
6 Use 'word_size' in a few more places, where it's appropriate.
7 (Fmake_bool_vector, sweep_vectors): Don't assume that there is no
8 padding before the data member of a bool vector.
9 (sweep_vectors): Use PSEUDOVECTOR_TYPEP, in an eassert, rather
10 than doing the check by hand with an abort ().
11
12012-07-18 Stefan Monnier <monnier@iro.umontreal.ca> 122012-07-18 Stefan Monnier <monnier@iro.umontreal.ca>
2 13
3 * eval.c (Fdefvar): Don't check constants since we only set the var if 14 * eval.c (Fdefvar): Don't check constants since we only set the var if
diff --git a/src/alloc.c b/src/alloc.c
index 0c3f5de6c3e..29aabdd4616 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -281,6 +281,14 @@ static void sweep_strings (void);
281static void free_misc (Lisp_Object); 281static void free_misc (Lisp_Object);
282extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; 282extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE;
283 283
284/* Handy constants for vectorlike objects. */
285enum
286 {
287 header_size = offsetof (struct Lisp_Vector, contents),
288 bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
289 word_size = sizeof (Lisp_Object)
290 };
291
284/* When scanning the C stack for live Lisp objects, Emacs keeps track 292/* When scanning the C stack for live Lisp objects, Emacs keeps track
285 of what memory allocated via lisp_malloc is intended for what 293 of what memory allocated via lisp_malloc is intended for what
286 purpose. This enumeration specifies the type of memory. */ 294 purpose. This enumeration specifies the type of memory. */
@@ -2356,6 +2364,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2356 ptrdiff_t length_in_chars; 2364 ptrdiff_t length_in_chars;
2357 EMACS_INT length_in_elts; 2365 EMACS_INT length_in_elts;
2358 int bits_per_value; 2366 int bits_per_value;
2367 int extra_bool_elts = ((bool_header_size - header_size + word_size - 1)
2368 / word_size);
2359 2369
2360 CHECK_NATNUM (length); 2370 CHECK_NATNUM (length);
2361 2371
@@ -2363,9 +2373,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2363 2373
2364 length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; 2374 length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value;
2365 2375
2366 /* We must allocate one more elements than LENGTH_IN_ELTS for the 2376 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil);
2367 slot `size' of the struct Lisp_Bool_Vector. */
2368 val = Fmake_vector (make_number (length_in_elts + 1), Qnil);
2369 2377
2370 /* No Lisp_Object to trace in there. */ 2378 /* No Lisp_Object to trace in there. */
2371 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); 2379 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0);
@@ -2874,12 +2882,10 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2874 2882
2875#define VECTOR_BLOCK_SIZE 4096 2883#define VECTOR_BLOCK_SIZE 4096
2876 2884
2877/* Handy constants for vectorlike objects. */ 2885/* Align allocation request sizes to be a multiple of ROUNDUP_SIZE. */
2878enum 2886enum
2879 { 2887 {
2880 header_size = offsetof (struct Lisp_Vector, contents), 2888 roundup_size = COMMON_MULTIPLE (word_size,
2881 word_size = sizeof (Lisp_Object),
2882 roundup_size = COMMON_MULTIPLE (sizeof (Lisp_Object),
2883 USE_LSB_TAG ? 1 << GCTYPEBITS : 1) 2889 USE_LSB_TAG ? 1 << GCTYPEBITS : 1)
2884 }; 2890 };
2885 2891
@@ -2905,7 +2911,7 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2905/* Size of the largest vector allocated from block. */ 2911/* Size of the largest vector allocated from block. */
2906 2912
2907#define VBLOCK_BYTES_MAX \ 2913#define VBLOCK_BYTES_MAX \
2908 vroundup ((VECTOR_BLOCK_BYTES / 2) - sizeof (Lisp_Object)) 2914 vroundup ((VECTOR_BLOCK_BYTES / 2) - word_size)
2909 2915
2910/* We maintain one free list for each possible block-allocated 2916/* We maintain one free list for each possible block-allocated
2911 vector size, and this is the number of free lists we have. */ 2917 vector size, and this is the number of free lists we have. */
@@ -3154,25 +3160,21 @@ sweep_vectors (void)
3154 total_vectors++; 3160 total_vectors++;
3155 if (vector->header.size & PSEUDOVECTOR_FLAG) 3161 if (vector->header.size & PSEUDOVECTOR_FLAG)
3156 { 3162 {
3157 if (((vector->header.size & PVEC_TYPE_MASK) 3163 struct Lisp_Bool_Vector *b = (struct Lisp_Bool_Vector *) vector;
3158 >> PSEUDOVECTOR_SIZE_BITS) == PVEC_BOOL_VECTOR) 3164
3159 { 3165 /* All non-bool pseudovectors are small enough to be allocated
3160 struct Lisp_Bool_Vector *b 3166 from vector blocks. This code should be redesigned if some
3161 = (struct Lisp_Bool_Vector *) vector; 3167 pseudovector type grows beyond VBLOCK_BYTES_MAX. */
3162 total_vector_bytes += header_size + sizeof (b->size) 3168 eassert (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR));
3163 + (b->size + BOOL_VECTOR_BITS_PER_CHAR - 1) 3169
3164 / BOOL_VECTOR_BITS_PER_CHAR; 3170 total_vector_bytes
3165 } 3171 += (bool_header_size
3166 else 3172 + ((b->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
3167 /* All other pseudovectors are small enough to be 3173 / BOOL_VECTOR_BITS_PER_CHAR));
3168 allocated from vector blocks. This code should
3169 be redesigned if some pseudovector type grows
3170 beyond VBLOCK_BYTES_MAX. */
3171 abort ();
3172 } 3174 }
3173 else 3175 else
3174 total_vector_bytes 3176 total_vector_bytes += (header_size
3175 += header_size + vector->header.size * word_size; 3177 + vector->header.size * word_size);
3176 vprev = &vector->header.next.vector; 3178 vprev = &vector->header.next.vector;
3177 } 3179 }
3178 else 3180 else
@@ -5261,8 +5263,7 @@ make_pure_vector (ptrdiff_t len)
5261{ 5263{
5262 Lisp_Object new; 5264 Lisp_Object new;
5263 struct Lisp_Vector *p; 5265 struct Lisp_Vector *p;
5264 size_t size = (offsetof (struct Lisp_Vector, contents) 5266 size_t size = header_size + len * word_size;
5265 + len * sizeof (Lisp_Object));
5266 5267
5267 p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike); 5268 p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike);
5268 XSETVECTOR (new, p); 5269 XSETVECTOR (new, p);