summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2013-11-13 18:39:28 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2013-11-13 18:39:28 -0800
commit2cf00efc1b0db0ddc26fa14239026dd2d12c7d59 (patch)
tree1bd3fcc233230eb7e2ffdee78da9433b3915623e /src/alloc.c
parentd672ac3c611453c624948ed8cc2ced65cadc3400 (diff)
downloademacs-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.c87
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