diff options
| author | Paul Eggert | 2012-07-18 10:26:43 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-07-18 10:26:43 -0700 |
| commit | d06714cb449d3eb3f58f4ed79053ca173db286fa (patch) | |
| tree | f84b9eb183e4ac255840eb721747da7238fd9cb1 /src | |
| parent | 5fbc0409ac3c51baf18d43b00ed00b56acc1c74b (diff) | |
| download | emacs-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/ChangeLog | 11 | ||||
| -rw-r--r-- | src/alloc.c | 55 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-07-18 Stefan Monnier <monnier@iro.umontreal.ca> | 12 | 2012-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); | |||
| 281 | static void free_misc (Lisp_Object); | 281 | static void free_misc (Lisp_Object); |
| 282 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; | 282 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; |
| 283 | 283 | ||
| 284 | /* Handy constants for vectorlike objects. */ | ||
| 285 | enum | ||
| 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. */ |
| 2878 | enum | 2886 | enum |
| 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); |