aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-11-18 10:37:25 -0800
committerPaul Eggert2013-11-18 10:37:25 -0800
commit87d86601022feb7a330fc6344cc85ec65563c1b6 (patch)
treebd7b266fcaca082eb4f3854ef32344d98106a58d /src
parent37c790b38599cc80a16c6a76152abbf8160fe2a1 (diff)
downloademacs-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')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/alloc.c21
-rw-r--r--src/data.c88
-rw-r--r--src/lisp.h1
4 files changed, 84 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a2dfa5bf613..21025c677fc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12013-11-18 Paul Eggert <eggert@cs.ucla.edu>
2
3 Always allocate at least one bits_word per bool vector.
4 See Daniel Colascione in:
5 http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html
6 * alloc.c (make_uninit_bool_vector): Always allocate at least one word.
7 * data.c (bool_vector_binop_driver): Rely on this. Tune.
8 * lisp.h (struct Lisp_Bool_vector): Document this.
9
12013-11-18 Eli Zaretskii <eliz@gnu.org> 102013-11-18 Eli Zaretskii <eliz@gnu.org>
2 11
3 * insdel.c (invalidate_buffer_caches): New function, consolidated 12 * insdel.c (invalidate_buffer_caches): New function, consolidated
diff --git a/src/alloc.c b/src/alloc.c
index f12fdc5c861..7c560fd0f0d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2066,20 +2066,21 @@ Lisp_Object
2066make_uninit_bool_vector (EMACS_INT nbits) 2066make_uninit_bool_vector (EMACS_INT nbits)
2067{ 2067{
2068 Lisp_Object val; 2068 Lisp_Object val;
2069 struct Lisp_Bool_Vector *p; 2069 EMACS_INT words0 = bool_vector_words (nbits);
2070 EMACS_INT word_bytes, needed_elements; 2070 EMACS_INT words = words0 + !words0; /* Allocate at least one word. */
2071 word_bytes = bool_vector_words (nbits) * sizeof (bits_word); 2071 EMACS_INT word_bytes = words * sizeof (bits_word);
2072 needed_elements = ((bool_header_size - header_size + word_bytes 2072 EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
2073 + word_size - 1) 2073 + word_size - 1)
2074 / word_size); 2074 / word_size);
2075 p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); 2075 struct Lisp_Bool_Vector *p
2076 = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
2076 XSETVECTOR (val, p); 2077 XSETVECTOR (val, p);
2077 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2078 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2078 p->size = nbits; 2079 p->size = nbits;
2079 2080
2080 /* Clear padding at the end. */ 2081 /* Clear padding at the end. If NBITS != 0 this initializes more
2081 if (nbits) 2082 than it needs to, but that's OK. */
2082 p->data[bool_vector_words (nbits) - 1] = 0; 2083 p->data[words - 1] = 0;
2083 2084
2084 return val; 2085 return val;
2085} 2086}
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)
diff --git a/src/lisp.h b/src/lisp.h
index a5aec41be38..8521c87e5d7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1213,6 +1213,7 @@ struct Lisp_Bool_Vector
1213 /* This is the size in bits. */ 1213 /* This is the size in bits. */
1214 EMACS_INT size; 1214 EMACS_INT size;
1215 /* The actual bits, packed into bytes. 1215 /* The actual bits, packed into bytes.
1216 Zeros fill out the last word as needed; there's always at least one word.
1216 The bits are in little-endian order in the bytes, and 1217 The bits are in little-endian order in the bytes, and
1217 the bytes are in little-endian order in the words. */ 1218 the bytes are in little-endian order in the words. */
1218 bits_word data[FLEXIBLE_ARRAY_MEMBER]; 1219 bits_word data[FLEXIBLE_ARRAY_MEMBER];