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.
This commit is contained in:
parent
37c790b385
commit
87d8660102
4 changed files with 85 additions and 36 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-11-18 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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.
|
||||
|
||||
2013-11-18 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* insdel.c (invalidate_buffer_caches): New function, consolidated
|
||||
|
|
21
src/alloc.c
21
src/alloc.c
|
@ -2066,20 +2066,21 @@ Lisp_Object
|
|||
make_uninit_bool_vector (EMACS_INT nbits)
|
||||
{
|
||||
Lisp_Object val;
|
||||
struct Lisp_Bool_Vector *p;
|
||||
EMACS_INT word_bytes, needed_elements;
|
||||
word_bytes = bool_vector_words (nbits) * sizeof (bits_word);
|
||||
needed_elements = ((bool_header_size - header_size + word_bytes
|
||||
+ word_size - 1)
|
||||
/ word_size);
|
||||
p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
|
||||
EMACS_INT words0 = bool_vector_words (nbits);
|
||||
EMACS_INT words = words0 + !words0; /* Allocate at least one word. */
|
||||
EMACS_INT word_bytes = words * sizeof (bits_word);
|
||||
EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
|
||||
+ word_size - 1)
|
||||
/ word_size);
|
||||
struct Lisp_Bool_Vector *p
|
||||
= (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
|
||||
XSETVECTOR (val, p);
|
||||
XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
|
||||
p->size = nbits;
|
||||
|
||||
/* Clear padding at the end. */
|
||||
if (nbits)
|
||||
p->data[bool_vector_words (nbits) - 1] = 0;
|
||||
/* Clear padding at the end. If NBITS != 0 this initializes more
|
||||
than it needs to, but that's OK. */
|
||||
p->data[words - 1] = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
|
90
src/data.c
90
src/data.c
|
@ -3025,9 +3025,7 @@ bool_vector_binop_driver (Lisp_Object op1,
|
|||
{
|
||||
EMACS_INT nr_bits;
|
||||
bits_word *adata, *bdata, *cdata;
|
||||
ptrdiff_t i;
|
||||
bool changed = 0;
|
||||
bits_word mword;
|
||||
ptrdiff_t i = 0;
|
||||
ptrdiff_t nr_words;
|
||||
|
||||
CHECK_BOOL_VECTOR (op1);
|
||||
|
@ -3037,45 +3035,82 @@ bool_vector_binop_driver (Lisp_Object op1,
|
|||
if (bool_vector_size (op2) != nr_bits)
|
||||
wrong_length_argument (op1, op2, dest);
|
||||
|
||||
nr_words = bool_vector_words (nr_bits);
|
||||
bdata = bool_vector_data (op1);
|
||||
cdata = bool_vector_data (op2);
|
||||
|
||||
if (NILP (dest))
|
||||
{
|
||||
dest = make_uninit_bool_vector (nr_bits);
|
||||
changed = 1;
|
||||
adata = bool_vector_data (dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_BOOL_VECTOR (dest);
|
||||
adata = bool_vector_data (dest);
|
||||
if (bool_vector_size (dest) != nr_bits)
|
||||
wrong_length_argument (op1, op2, dest);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case bool_vector_exclusive_or:
|
||||
while (adata[i] == (bdata[i] ^ cdata[i]))
|
||||
if (! (++i < nr_words))
|
||||
return Qnil;
|
||||
break;
|
||||
|
||||
case bool_vector_subsetp:
|
||||
case bool_vector_union:
|
||||
while (adata[i] == (bdata[i] | cdata[i]))
|
||||
if (! (++i < nr_words))
|
||||
return Qnil;
|
||||
break;
|
||||
|
||||
case bool_vector_intersection:
|
||||
while (adata[i] == (bdata[i] & cdata[i]))
|
||||
if (! (++i < nr_words))
|
||||
return Qnil;
|
||||
break;
|
||||
|
||||
case bool_vector_set_difference:
|
||||
while (adata[i] == (bdata[i] &~ cdata[i]))
|
||||
if (! (++i < nr_words))
|
||||
return Qnil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nr_words = bool_vector_words (nr_bits);
|
||||
|
||||
adata = bool_vector_data (dest);
|
||||
bdata = bool_vector_data (op1);
|
||||
cdata = bool_vector_data (op2);
|
||||
|
||||
for (i = 0; i < nr_words; i++)
|
||||
switch (op)
|
||||
{
|
||||
if (op == bool_vector_exclusive_or)
|
||||
mword = bdata[i] ^ cdata[i];
|
||||
else if (op == bool_vector_union || op == bool_vector_subsetp)
|
||||
mword = bdata[i] | cdata[i];
|
||||
else if (op == bool_vector_intersection)
|
||||
mword = bdata[i] & cdata[i];
|
||||
else if (op == bool_vector_set_difference)
|
||||
mword = bdata[i] &~ cdata[i];
|
||||
else
|
||||
abort ();
|
||||
case bool_vector_exclusive_or:
|
||||
do
|
||||
adata[i] = bdata[i] ^ cdata[i];
|
||||
while (++i < nr_words);
|
||||
break;
|
||||
|
||||
if (! changed)
|
||||
changed = adata[i] != mword;
|
||||
case bool_vector_subsetp:
|
||||
break;
|
||||
|
||||
if (op != bool_vector_subsetp)
|
||||
adata[i] = mword;
|
||||
case bool_vector_union:
|
||||
do
|
||||
adata[i] = bdata[i] | cdata[i];
|
||||
while (++i < nr_words);
|
||||
break;
|
||||
|
||||
case bool_vector_intersection:
|
||||
do
|
||||
adata[i] = bdata[i] & cdata[i];
|
||||
while (++i < nr_words);
|
||||
break;
|
||||
|
||||
case bool_vector_set_difference:
|
||||
do
|
||||
adata[i] = bdata[i] &~ cdata[i];
|
||||
while (++i < nr_words);
|
||||
break;
|
||||
}
|
||||
|
||||
return changed ? dest : Qnil;
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* PRECONDITION must be true. Return VALUE. This odd construction
|
||||
|
@ -3314,7 +3349,10 @@ index into the vector. */)
|
|||
mword = bits_word_to_host_endian (adata[pos]);
|
||||
mword ^= twiddle;
|
||||
mword >>= offset;
|
||||
|
||||
/* Do not count the pad bits. */
|
||||
mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
|
||||
|
||||
count = count_trailing_zero_bits (mword);
|
||||
pos++;
|
||||
if (count + offset < BITS_PER_BITS_WORD)
|
||||
|
|
|
@ -1213,6 +1213,7 @@ struct Lisp_Bool_Vector
|
|||
/* This is the size in bits. */
|
||||
EMACS_INT size;
|
||||
/* The actual bits, packed into bytes.
|
||||
Zeros fill out the last word as needed; there's always at least one word.
|
||||
The bits are in little-endian order in the bytes, and
|
||||
the bytes are in little-endian order in the words. */
|
||||
bits_word data[FLEXIBLE_ARRAY_MEMBER];
|
||||
|
|
Loading…
Add table
Reference in a new issue