From ca95b3ebc8587780966cee0acfe0f7822e895f83 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 3 Jul 2012 20:35:53 +0400 Subject: [PATCH] Fix block vector allocation code to allow VECTOR_BLOCK_SIZE values which aren't power of 2. * alloc.c (VECTOR_FREE_LIST_SIZE_MASK): New macro. Verify it's value and the value of VECTOR_BLOCK_SIZE. Adjust users accordingly. --- src/ChangeLog | 8 ++++++++ src/alloc.c | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index aca64a79961..e3993981317 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-07-03 Dmitry Antipov + + Fix block vector allocation code to allow VECTOR_BLOCK_SIZE + values which aren't power of 2. + * alloc.c (VECTOR_FREE_LIST_SIZE_MASK): New macro. Verify + it's value and the value of VECTOR_BLOCK_SIZE. Adjust users + accordingly. + 2012-07-03 Stefan Monnier * lisp.h (Lisp_Misc, Lisp_Fwd): Move around to group better. diff --git a/src/alloc.c b/src/alloc.c index 19972d54670..b1e2ed0a2ed 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2869,6 +2869,12 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, #define VECTOR_BLOCK_SIZE 4096 +/* This special value is used to calculate vector size when the vector is + on a free list. It should be VECTOR_BLOCK_SIZE rounded up to nearest + power of two, minus one. */ + +#define VECTOR_FREE_LIST_SIZE_MASK 4095 + /* Handy constants for vectorlike objects. */ enum { @@ -2881,6 +2887,11 @@ enum /* ROUNDUP_SIZE must be a power of 2. */ verify ((roundup_size & (roundup_size - 1)) == 0); +/* Verify assumptions described above. */ +verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); +verify ((VECTOR_FREE_LIST_SIZE_MASK + 1) >= VECTOR_BLOCK_SIZE); +verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0); + /* Round up X to nearest mult-of-ROUNDUP_SIZE. */ #define vroundup(x) (((x) + (roundup_size - 1)) & ~(roundup_size - 1)) @@ -2908,7 +2919,7 @@ verify ((roundup_size & (roundup_size - 1)) == 0); this special value ORed with vector's memory footprint size. */ #define VECTOR_FREE_LIST_FLAG (~(ARRAY_MARK_FLAG | PSEUDOVECTOR_FLAG \ - | (VECTOR_BLOCK_SIZE - 1))) + | VECTOR_FREE_LIST_SIZE_MASK)) /* Common shortcut to advance vector pointer over a block data. */ @@ -3087,7 +3098,7 @@ sweep_vectors (void) if ((vector->header.size & VECTOR_FREE_LIST_FLAG) == VECTOR_FREE_LIST_FLAG) vector->header.next.nbytes = - vector->header.size & (VECTOR_BLOCK_SIZE - 1); + vector->header.size & VECTOR_FREE_LIST_SIZE_MASK; next = ADVANCE (vector, vector->header.next.nbytes); @@ -3100,7 +3111,7 @@ sweep_vectors (void) break; if ((next->header.size & VECTOR_FREE_LIST_FLAG) == VECTOR_FREE_LIST_FLAG) - nbytes = next->header.size & (VECTOR_BLOCK_SIZE - 1); + nbytes = next->header.size & VECTOR_FREE_LIST_SIZE_MASK; else nbytes = next->header.next.nbytes; vector->header.next.nbytes += nbytes; @@ -4334,7 +4345,7 @@ live_vector_p (struct mem_node *m, void *p) if ((vector->header.size & VECTOR_FREE_LIST_FLAG) == VECTOR_FREE_LIST_FLAG) vector = ADVANCE (vector, (vector->header.size - & (VECTOR_BLOCK_SIZE - 1))); + & VECTOR_FREE_LIST_SIZE_MASK)); else if (vector == p) return 1; else -- 2.39.2