diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2013-11-13 18:39:28 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2013-11-13 18:39:28 -0800 |
commit | 2cf00efc1b0db0ddc26fa14239026dd2d12c7d59 (patch) | |
tree | 1bd3fcc233230eb7e2ffdee78da9433b3915623e /src/alloc.c | |
parent | d672ac3c611453c624948ed8cc2ced65cadc3400 (diff) | |
download | emacs-2cf00efc1b0db0ddc26fa14239026dd2d12c7d59.tar.gz |
Simplify, port and tune bool vector implementation.
* configure.ac (BITSIZEOF_SIZE_T, SIZEOF_SIZE_T): Remove.
* src/alloc.c (bool_vector_exact_payload_bytes)
(bool_vector_payload_bytes): Remove.
(bool_vector_fill): Return its argument.
* src/alloc.c (bool_vector_fill):
* src/lread.c (read1):
* src/print.c (print_object):
Simplify by using bool_vector_bytes.
* src/alloc.c (make_uninit_bool_vector):
New function, broken out from Fmake_bool_vector.
(Fmake_bool_vector): Use it. Use tail call.
(make_uninit_bool_vector, vector_nbytes): Simplify size calculations.
* src/data.c (BITS_PER_ULL): New constant.
(ULLONG_MAX, count_one_bits_ll): Fall back on long counterparts
if long long versions don't exist.
(shift_right_ull): New function.
(count_one_bits_word): New function, replacing popcount_bits_word
macro. Don't assume that bits_word is no wider than long long.
(count_one_bits_word, count_trailing_zero_bits):
Don't assume that bits_word is no wider than long long.
* src/data.c (bool_vector_binop_driver, bool_vector_not):
* src/fns.c (Fcopy_sequence):
* src/lread.c (read1):
Create an uninitialized destination, to avoid needless work.
(internal_equal): Simplify.
(Ffillarray): Prefer tail call.
* src/data.c (bool_vector_binop_driver): Don't assume bit vectors always
contain at least one word.
(bits_word_to_host_endian): Prefer if to #if. Don't assume
chars are narrower than ints.
* src/data.c (Fbool_vector_count_matches, Fbool_vector_count_matches_at):
* src/fns.c (Fcopy_sequence):
Simplify and tune.
* src/lisp.h (bits_word, BITS_WORD_MAX, BITS_PER_BITS_WORD):
Don't try to port to hosts where bits_word values have holes; the
code wouldn't work there anyway. Verify this assumption, though.
(bool_vector_bytes): New function.
(make_uninit_bool_vector): New decl.
(bool_vector_fill): Now returns Lisp_Object.
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/src/alloc.c b/src/alloc.c index bc5ed6d94bb..f12fdc5c861 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2041,26 +2041,10 @@ INIT must be an integer that represents a character. */) return val; } -static EMACS_INT -bool_vector_exact_payload_bytes (EMACS_INT nbits) -{ - eassume (0 <= nbits); - return (nbits + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR; -} - -static EMACS_INT -bool_vector_payload_bytes (EMACS_INT nbits) -{ - EMACS_INT exact_needed_bytes = bool_vector_exact_payload_bytes (nbits); +/* Fill A with 1 bits if INIT is non-nil, and with 0 bits otherwise. + Return A. */ - /* Always allocate at least one machine word of payload so that - bool-vector operations in data.c don't need a special case - for empty vectors. */ - return ROUNDUP (exact_needed_bytes + !exact_needed_bytes, - sizeof (bits_word)); -} - -void +Lisp_Object bool_vector_fill (Lisp_Object a, Lisp_Object init) { EMACS_INT nbits = bool_vector_size (a); @@ -2068,48 +2052,50 @@ bool_vector_fill (Lisp_Object a, Lisp_Object init) { unsigned char *data = bool_vector_uchar_data (a); int pattern = NILP (init) ? 0 : (1 << BOOL_VECTOR_BITS_PER_CHAR) - 1; - ptrdiff_t nbytes = ((nbits + BOOL_VECTOR_BITS_PER_CHAR - 1) - / BOOL_VECTOR_BITS_PER_CHAR); + ptrdiff_t nbytes = bool_vector_bytes (nbits); int last_mask = ~ (~0 << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1)); memset (data, pattern, nbytes - 1); data[nbytes - 1] = pattern & last_mask; } + return a; } -DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, - doc: /* Return a new bool-vector of length LENGTH, using INIT for each element. -LENGTH must be a number. INIT matters only in whether it is t or nil. */) - (Lisp_Object length, Lisp_Object init) +/* Return a newly allocated, uninitialized bool vector of size NBITS. */ + +Lisp_Object +make_uninit_bool_vector (EMACS_INT nbits) { Lisp_Object val; struct Lisp_Bool_Vector *p; - EMACS_INT exact_payload_bytes, total_payload_bytes, needed_elements; - - CHECK_NATNUM (length); - - exact_payload_bytes = bool_vector_exact_payload_bytes (XFASTINT (length)); - total_payload_bytes = bool_vector_payload_bytes (XFASTINT (length)); - - needed_elements = ((bool_header_size - header_size + total_payload_bytes + 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); XSETVECTOR (val, p); XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); - - p->size = XFASTINT (length); - bool_vector_fill (val, init); + p->size = nbits; /* Clear padding at the end. */ - eassume (exact_payload_bytes <= total_payload_bytes); - memset (bool_vector_uchar_data (val) + exact_payload_bytes, - 0, - total_payload_bytes - exact_payload_bytes); + if (nbits) + p->data[bool_vector_words (nbits) - 1] = 0; return val; } +DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, + doc: /* Return a new bool-vector of length LENGTH, using INIT for each element. +LENGTH must be a number. INIT matters only in whether it is t or nil. */) + (Lisp_Object length, Lisp_Object init) +{ + Lisp_Object val; + + CHECK_NATNUM (length); + val = make_uninit_bool_vector (XFASTINT (length)); + return bool_vector_fill (val, init); +} + /* Make a string from NBYTES bytes at CONTENTS, and compute the number of characters from the contents. This string may be unibyte or @@ -2858,24 +2844,27 @@ static ptrdiff_t vector_nbytes (struct Lisp_Vector *v) { ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG; + ptrdiff_t nwords; if (size & PSEUDOVECTOR_FLAG) { if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR)) { struct Lisp_Bool_Vector *bv = (struct Lisp_Bool_Vector *) v; - ptrdiff_t payload_bytes = bool_vector_payload_bytes (bv->size); - size = bool_header_size + payload_bytes; + ptrdiff_t word_bytes = (bool_vector_words (bv->size) + * sizeof (bits_word)); + ptrdiff_t boolvec_bytes = bool_header_size + word_bytes; + verify (header_size <= bool_header_size); + nwords = (boolvec_bytes - header_size + word_size - 1) / word_size; } else - size = (header_size - + ((size & PSEUDOVECTOR_SIZE_MASK) - + ((size & PSEUDOVECTOR_REST_MASK) - >> PSEUDOVECTOR_SIZE_BITS)) * word_size); + nwords = ((size & PSEUDOVECTOR_SIZE_MASK) + + ((size & PSEUDOVECTOR_REST_MASK) + >> PSEUDOVECTOR_SIZE_BITS)); } else - size = header_size + size * word_size; - return vroundup (size); + nwords = size; + return vroundup (header_size + word_size * nwords); } /* Release extra resources still in use by VECTOR, which may be any |