diff options
| author | Paul Eggert | 2013-11-18 10:37:25 -0800 |
|---|---|---|
| committer | Paul Eggert | 2013-11-18 10:37:25 -0800 |
| commit | 87d86601022feb7a330fc6344cc85ec65563c1b6 (patch) | |
| tree | bd7b266fcaca082eb4f3854ef32344d98106a58d /src/data.c | |
| parent | 37c790b38599cc80a16c6a76152abbf8160fe2a1 (diff) | |
| download | emacs-87d86601022feb7a330fc6344cc85ec65563c1b6.tar.gz emacs-87d86601022feb7a330fc6344cc85ec65563c1b6.zip | |
Always allocate at least one bits_word per bool vector.
See Daniel Colascione in:
http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html
* alloc.c (make_uninit_bool_vector): Always allocate at least one word.
* data.c (bool_vector_binop_driver): Rely on this. Tune.
* lisp.h (struct Lisp_Bool_vector): Document this.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/src/data.c b/src/data.c index d0171b5d758..b8b0f248dfa 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -3025,9 +3025,7 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3025 | { | 3025 | { |
| 3026 | EMACS_INT nr_bits; | 3026 | EMACS_INT nr_bits; |
| 3027 | bits_word *adata, *bdata, *cdata; | 3027 | bits_word *adata, *bdata, *cdata; |
| 3028 | ptrdiff_t i; | 3028 | ptrdiff_t i = 0; |
| 3029 | bool changed = 0; | ||
| 3030 | bits_word mword; | ||
| 3031 | ptrdiff_t nr_words; | 3029 | ptrdiff_t nr_words; |
| 3032 | 3030 | ||
| 3033 | CHECK_BOOL_VECTOR (op1); | 3031 | CHECK_BOOL_VECTOR (op1); |
| @@ -3037,45 +3035,82 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3037 | if (bool_vector_size (op2) != nr_bits) | 3035 | if (bool_vector_size (op2) != nr_bits) |
| 3038 | wrong_length_argument (op1, op2, dest); | 3036 | wrong_length_argument (op1, op2, dest); |
| 3039 | 3037 | ||
| 3038 | nr_words = bool_vector_words (nr_bits); | ||
| 3039 | bdata = bool_vector_data (op1); | ||
| 3040 | cdata = bool_vector_data (op2); | ||
| 3041 | |||
| 3040 | if (NILP (dest)) | 3042 | if (NILP (dest)) |
| 3041 | { | 3043 | { |
| 3042 | dest = make_uninit_bool_vector (nr_bits); | 3044 | dest = make_uninit_bool_vector (nr_bits); |
| 3043 | changed = 1; | 3045 | adata = bool_vector_data (dest); |
| 3044 | } | 3046 | } |
| 3045 | else | 3047 | else |
| 3046 | { | 3048 | { |
| 3047 | CHECK_BOOL_VECTOR (dest); | 3049 | CHECK_BOOL_VECTOR (dest); |
| 3050 | adata = bool_vector_data (dest); | ||
| 3048 | if (bool_vector_size (dest) != nr_bits) | 3051 | if (bool_vector_size (dest) != nr_bits) |
| 3049 | wrong_length_argument (op1, op2, dest); | 3052 | wrong_length_argument (op1, op2, dest); |
| 3050 | } | ||
| 3051 | 3053 | ||
| 3052 | nr_words = bool_vector_words (nr_bits); | 3054 | switch (op) |
| 3055 | { | ||
| 3056 | case bool_vector_exclusive_or: | ||
| 3057 | while (adata[i] == (bdata[i] ^ cdata[i])) | ||
| 3058 | if (! (++i < nr_words)) | ||
| 3059 | return Qnil; | ||
| 3060 | break; | ||
| 3053 | 3061 | ||
| 3054 | adata = bool_vector_data (dest); | 3062 | case bool_vector_subsetp: |
| 3055 | bdata = bool_vector_data (op1); | 3063 | case bool_vector_union: |
| 3056 | cdata = bool_vector_data (op2); | 3064 | while (adata[i] == (bdata[i] | cdata[i])) |
| 3065 | if (! (++i < nr_words)) | ||
| 3066 | return Qnil; | ||
| 3067 | break; | ||
| 3068 | |||
| 3069 | case bool_vector_intersection: | ||
| 3070 | while (adata[i] == (bdata[i] & cdata[i])) | ||
| 3071 | if (! (++i < nr_words)) | ||
| 3072 | return Qnil; | ||
| 3073 | break; | ||
| 3057 | 3074 | ||
| 3058 | for (i = 0; i < nr_words; i++) | 3075 | case bool_vector_set_difference: |
| 3076 | while (adata[i] == (bdata[i] &~ cdata[i])) | ||
| 3077 | if (! (++i < nr_words)) | ||
| 3078 | return Qnil; | ||
| 3079 | break; | ||
| 3080 | } | ||
| 3081 | } | ||
| 3082 | |||
| 3083 | switch (op) | ||
| 3059 | { | 3084 | { |
| 3060 | if (op == bool_vector_exclusive_or) | 3085 | case bool_vector_exclusive_or: |
| 3061 | mword = bdata[i] ^ cdata[i]; | 3086 | do |
| 3062 | else if (op == bool_vector_union || op == bool_vector_subsetp) | 3087 | adata[i] = bdata[i] ^ cdata[i]; |
| 3063 | mword = bdata[i] | cdata[i]; | 3088 | while (++i < nr_words); |
| 3064 | else if (op == bool_vector_intersection) | 3089 | break; |
| 3065 | mword = bdata[i] & cdata[i]; | 3090 | |
| 3066 | else if (op == bool_vector_set_difference) | 3091 | case bool_vector_subsetp: |
| 3067 | mword = bdata[i] &~ cdata[i]; | 3092 | break; |
| 3068 | else | 3093 | |
| 3069 | abort (); | 3094 | case bool_vector_union: |
| 3095 | do | ||
| 3096 | adata[i] = bdata[i] | cdata[i]; | ||
| 3097 | while (++i < nr_words); | ||
| 3098 | break; | ||
| 3070 | 3099 | ||
| 3071 | if (! changed) | 3100 | case bool_vector_intersection: |
| 3072 | changed = adata[i] != mword; | 3101 | do |
| 3102 | adata[i] = bdata[i] & cdata[i]; | ||
| 3103 | while (++i < nr_words); | ||
| 3104 | break; | ||
| 3073 | 3105 | ||
| 3074 | if (op != bool_vector_subsetp) | 3106 | case bool_vector_set_difference: |
| 3075 | adata[i] = mword; | 3107 | do |
| 3108 | adata[i] = bdata[i] &~ cdata[i]; | ||
| 3109 | while (++i < nr_words); | ||
| 3110 | break; | ||
| 3076 | } | 3111 | } |
| 3077 | 3112 | ||
| 3078 | return changed ? dest : Qnil; | 3113 | return dest; |
| 3079 | } | 3114 | } |
| 3080 | 3115 | ||
| 3081 | /* PRECONDITION must be true. Return VALUE. This odd construction | 3116 | /* PRECONDITION must be true. Return VALUE. This odd construction |
| @@ -3314,7 +3349,10 @@ index into the vector. */) | |||
| 3314 | mword = bits_word_to_host_endian (adata[pos]); | 3349 | mword = bits_word_to_host_endian (adata[pos]); |
| 3315 | mword ^= twiddle; | 3350 | mword ^= twiddle; |
| 3316 | mword >>= offset; | 3351 | mword >>= offset; |
| 3352 | |||
| 3353 | /* Do not count the pad bits. */ | ||
| 3317 | mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); | 3354 | mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); |
| 3355 | |||
| 3318 | count = count_trailing_zero_bits (mword); | 3356 | count = count_trailing_zero_bits (mword); |
| 3319 | pos++; | 3357 | pos++; |
| 3320 | if (count + offset < BITS_PER_BITS_WORD) | 3358 | if (count + offset < BITS_PER_BITS_WORD) |