diff options
| author | Paul Eggert | 2013-11-04 23:11:24 -0800 |
|---|---|---|
| committer | Paul Eggert | 2013-11-04 23:11:24 -0800 |
| commit | df5b49306e8e82e2f18ed3243700c11ca7835750 (patch) | |
| tree | d98fffc7d11d4565b6132e83f54ca3f3c547b1d4 /src/data.c | |
| parent | 693698093480628b7438ca0fd1614b00acfd1137 (diff) | |
| download | emacs-df5b49306e8e82e2f18ed3243700c11ca7835750.tar.gz emacs-df5b49306e8e82e2f18ed3243700c11ca7835750.zip | |
Simplify and port recent bool vector changes.
* configure.ac (BITSIZEOF_SIZE_T, SIZEOF_SIZE_T):
New symbols to configure.
* src/alloc.c (ROUNDUP): Move here from lisp.h, since it's now used
only in this file. Use a more-efficient implementation if the
second argument is a power of 2.
(ALIGN): Rewrite in terms of ROUNDUP. Make it a function.
Remove no-longer-necessary compile-time checks.
(bool_vector_exact_payload_bytes): New function.
(bool_vector_payload_bytes): Remove 2nd arg; callers that need
exact payload changed to call the new function. Do not assume
that the arg or result fits in ptrdiff_t.
(bool_vector_fill): New function.
(Fmake_bool_vector): Use it. Don't assume bit counts fit
in ptrdiff_t.
(vroundup_ct): Don't assume arg fits in size_t.
* src/category.c (SET_CATEGORY_SET): Remove. All callers now just
invoke set_category_set.
(set_category_set): 2nd arg is now EMACS_INT and 3rd is now bool.
All callers changed. Use bool_vector_set.
* src/category.h (XCATEGORY_SET): Remove; no longer needed.
(CATEGORY_MEMBER): Now a function. Rewrite in terms of
bool_vector_bitref.
* src/data.c (Faref): Use bool_vector_ref.
(Faset): Use bool_vector_set.
(bits_word_to_host_endian): Don't assume you can shift by CHAR_BIT.
(Fbool_vector_not, Fbool_vector_count_matches)
(Fbool_vector_count_matches_at): Don't assume CHAR_BIT == 8.
* src/fns.c (concat): Use bool_vector_ref.
(Ffillarray): Use bool_vector_fill.
(mapcar1): Use bool_vector_ref.
(sxhash_bool_vector): Hash words, not bytes.
* src/lisp.h (BOOL_VECTOR_BITS_PER_CHAR): Now a macro as well as
a constant, since it's now used in #if.
(bits_word, BITS_WORD_MAX, BITS_PER_BITS_WORD): Fall back on
unsigned char on unusual architectures, so that we no longer
assume that the number of bits per bits_word is a power of two or
is a multiple of 8 or of CHAR_BIT.
(Qt): Add forward decl.
(struct Lisp_Bool_Vector): Don't assume EMACS_INT is aligned
at least as strictly as bits_word.
(bool_vector_data, bool_vector_uchar_data): New accessors.
All data structure accesses changed to use them.
(bool_vector_words, bool_vector_bitref, bool_vector_ref)
(bool_vector_set): New functions.
(bool_vector_fill): New decl.
(ROUNDUP): Move to alloc.c as described above.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 51 |
1 files changed, 18 insertions, 33 deletions
diff --git a/src/data.c b/src/data.c index 22d051ef932..4043fbe279b 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2141,13 +2141,9 @@ or a byte-code object. IDX starts at 0. */) | |||
| 2141 | } | 2141 | } |
| 2142 | else if (BOOL_VECTOR_P (array)) | 2142 | else if (BOOL_VECTOR_P (array)) |
| 2143 | { | 2143 | { |
| 2144 | int val; | ||
| 2145 | |||
| 2146 | if (idxval < 0 || idxval >= bool_vector_size (array)) | 2144 | if (idxval < 0 || idxval >= bool_vector_size (array)) |
| 2147 | args_out_of_range (array, idx); | 2145 | args_out_of_range (array, idx); |
| 2148 | 2146 | return bool_vector_ref (array, idxval); | |
| 2149 | val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR]; | ||
| 2150 | return (val & (1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)) ? Qt : Qnil); | ||
| 2151 | } | 2147 | } |
| 2152 | else if (CHAR_TABLE_P (array)) | 2148 | else if (CHAR_TABLE_P (array)) |
| 2153 | { | 2149 | { |
| @@ -2191,18 +2187,9 @@ bool-vector. IDX starts at 0. */) | |||
| 2191 | } | 2187 | } |
| 2192 | else if (BOOL_VECTOR_P (array)) | 2188 | else if (BOOL_VECTOR_P (array)) |
| 2193 | { | 2189 | { |
| 2194 | int val; | ||
| 2195 | |||
| 2196 | if (idxval < 0 || idxval >= bool_vector_size (array)) | 2190 | if (idxval < 0 || idxval >= bool_vector_size (array)) |
| 2197 | args_out_of_range (array, idx); | 2191 | args_out_of_range (array, idx); |
| 2198 | 2192 | bool_vector_set (array, idxval, !NILP (newelt)); | |
| 2199 | val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR]; | ||
| 2200 | |||
| 2201 | if (! NILP (newelt)) | ||
| 2202 | val |= 1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR); | ||
| 2203 | else | ||
| 2204 | val &= ~(1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)); | ||
| 2205 | XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR] = val; | ||
| 2206 | } | 2193 | } |
| 2207 | else if (CHAR_TABLE_P (array)) | 2194 | else if (CHAR_TABLE_P (array)) |
| 2208 | { | 2195 | { |
| @@ -3033,11 +3020,11 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3033 | wrong_length_argument (op1, op2, dest); | 3020 | wrong_length_argument (op1, op2, dest); |
| 3034 | } | 3021 | } |
| 3035 | 3022 | ||
| 3036 | nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; | 3023 | nr_words = bool_vector_words (nr_bits); |
| 3037 | 3024 | ||
| 3038 | adata = (bits_word *) XBOOL_VECTOR (dest)->data; | 3025 | adata = bool_vector_data (dest); |
| 3039 | bdata = (bits_word *) XBOOL_VECTOR (op1)->data; | 3026 | bdata = bool_vector_data (op1); |
| 3040 | cdata = (bits_word *) XBOOL_VECTOR (op2)->data; | 3027 | cdata = bool_vector_data (op2); |
| 3041 | i = 0; | 3028 | i = 0; |
| 3042 | do | 3029 | do |
| 3043 | { | 3030 | { |
| @@ -3110,8 +3097,9 @@ bits_word_to_host_endian (bits_word val) | |||
| 3110 | bits_word r = 0; | 3097 | bits_word r = 0; |
| 3111 | for (i = 0; i < sizeof val; i++) | 3098 | for (i = 0; i < sizeof val; i++) |
| 3112 | { | 3099 | { |
| 3113 | r = (r << CHAR_BIT) | (val & ((1u << CHAR_BIT) - 1)); | 3100 | r = ((r << 1 << (CHAR_BIT - 1)) |
| 3114 | val >>= CHAR_BIT; | 3101 | | (val & ((1u << 1 << (CHAR_BIT - 1)) - 1))); |
| 3102 | val = val >> 1 >> (CHAR_BIT - 1); | ||
| 3115 | } | 3103 | } |
| 3116 | return r; | 3104 | return r; |
| 3117 | #endif | 3105 | #endif |
| @@ -3181,7 +3169,6 @@ Return the destination vector. */) | |||
| 3181 | EMACS_INT nr_bits; | 3169 | EMACS_INT nr_bits; |
| 3182 | bits_word *bdata, *adata; | 3170 | bits_word *bdata, *adata; |
| 3183 | ptrdiff_t i; | 3171 | ptrdiff_t i; |
| 3184 | bits_word mword; | ||
| 3185 | 3172 | ||
| 3186 | CHECK_BOOL_VECTOR (a); | 3173 | CHECK_BOOL_VECTOR (a); |
| 3187 | nr_bits = bool_vector_size (a); | 3174 | nr_bits = bool_vector_size (a); |
| @@ -3195,15 +3182,15 @@ Return the destination vector. */) | |||
| 3195 | wrong_length_argument (a, b, Qnil); | 3182 | wrong_length_argument (a, b, Qnil); |
| 3196 | } | 3183 | } |
| 3197 | 3184 | ||
| 3198 | bdata = (bits_word *) XBOOL_VECTOR (b)->data; | 3185 | bdata = bool_vector_data (b); |
| 3199 | adata = (bits_word *) XBOOL_VECTOR (a)->data; | 3186 | adata = bool_vector_data (a); |
| 3200 | 3187 | ||
| 3201 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++) | 3188 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++) |
| 3202 | bdata[i] = ~adata[i]; | 3189 | bdata[i] = BITS_WORD_MAX & ~adata[i]; |
| 3203 | 3190 | ||
| 3204 | if (nr_bits % BITS_PER_BITS_WORD) | 3191 | if (nr_bits % BITS_PER_BITS_WORD) |
| 3205 | { | 3192 | { |
| 3206 | mword = bits_word_to_host_endian (adata[i]); | 3193 | bits_word mword = bits_word_to_host_endian (adata[i]); |
| 3207 | mword = ~mword; | 3194 | mword = ~mword; |
| 3208 | mword &= bool_vector_spare_mask (nr_bits); | 3195 | mword &= bool_vector_spare_mask (nr_bits); |
| 3209 | bdata[i] = bits_word_to_host_endian (mword); | 3196 | bdata[i] = bits_word_to_host_endian (mword); |
| @@ -3228,8 +3215,8 @@ A must be a bool vector. B is a generalized bool. */) | |||
| 3228 | 3215 | ||
| 3229 | nr_bits = bool_vector_size (a); | 3216 | nr_bits = bool_vector_size (a); |
| 3230 | count = 0; | 3217 | count = 0; |
| 3231 | match = NILP (b) ? -1 : 0; | 3218 | match = NILP (b) ? BITS_WORD_MAX : 0; |
| 3232 | adata = (bits_word *) XBOOL_VECTOR (a)->data; | 3219 | adata = bool_vector_data (a); |
| 3233 | 3220 | ||
| 3234 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; ++i) | 3221 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; ++i) |
| 3235 | count += popcount_bits_word (adata[i] ^ match); | 3222 | count += popcount_bits_word (adata[i] ^ match); |
| @@ -3269,10 +3256,8 @@ index into the vector. */) | |||
| 3269 | if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ | 3256 | if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ |
| 3270 | args_out_of_range (a, i); | 3257 | args_out_of_range (a, i); |
| 3271 | 3258 | ||
| 3272 | adata = (bits_word *) XBOOL_VECTOR (a)->data; | 3259 | adata = bool_vector_data (a); |
| 3273 | 3260 | nr_words = bool_vector_words (nr_bits); | |
| 3274 | nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; | ||
| 3275 | |||
| 3276 | pos = XFASTINT (i) / BITS_PER_BITS_WORD; | 3261 | pos = XFASTINT (i) / BITS_PER_BITS_WORD; |
| 3277 | offset = XFASTINT (i) % BITS_PER_BITS_WORD; | 3262 | offset = XFASTINT (i) % BITS_PER_BITS_WORD; |
| 3278 | count = 0; | 3263 | count = 0; |
| @@ -3280,7 +3265,7 @@ index into the vector. */) | |||
| 3280 | /* By XORing with twiddle, we transform the problem of "count | 3265 | /* By XORing with twiddle, we transform the problem of "count |
| 3281 | consecutive equal values" into "count the zero bits". The latter | 3266 | consecutive equal values" into "count the zero bits". The latter |
| 3282 | operation usually has hardware support. */ | 3267 | operation usually has hardware support. */ |
| 3283 | twiddle = NILP (b) ? 0 : -1; | 3268 | twiddle = NILP (b) ? 0 : BITS_WORD_MAX; |
| 3284 | 3269 | ||
| 3285 | /* Scan the remainder of the mword at the current offset. */ | 3270 | /* Scan the remainder of the mword at the current offset. */ |
| 3286 | if (pos < nr_words && offset != 0) | 3271 | if (pos < nr_words && offset != 0) |