Another tweak to vectorlike_header change.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 12 Nov 2012 01:09:34 +0000 (17:09 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 12 Nov 2012 01:09:34 +0000 (17:09 -0800)
* alloc.c (struct Lisp_Vectorlike_Free, NEXT_IN_FREE_LIST):
Remove, and replace all uses with ...
(next_in_free_list, set_next_in_free_list):
New functions, which respect C's aliasing rules better.

src/ChangeLog
src/alloc.c

index 82a2245..97d04cb 100644 (file)
@@ -1,3 +1,11 @@
+2012-11-12  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Another tweak to vectorlike_header change.
+       * alloc.c (struct Lisp_Vectorlike_Free, NEXT_IN_FREE_LIST):
+       Remove, and replace all uses with ...
+       (next_in_free_list, set_next_in_free_list):
+       New functions, which respect C's aliasing rules better.
+
 2012-11-11  Paul Eggert  <eggert@cs.ucla.edu>
 
        * window.c (list4i): Rename from 'quad'.  All uses changed.
index 0a3d469..a66a752 100644 (file)
@@ -2611,18 +2611,21 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
 
 #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
 
-/* This special type is used to represent any block-allocated vectorlike
-   object on the free list.  */
-
-struct Lisp_Vectorlike_Free
+/* Get and set the next field in block-allocated vectorlike objects on
+   the free list.  Doing it this way respects C's aliasing rules.
+   We could instead make 'contents' a union, but that would mean
+   changes everywhere that the code uses 'contents'.  */
+static struct Lisp_Vector *
+next_in_free_list (struct Lisp_Vector *v)
 {
-  struct vectorlike_header header;
-  struct Lisp_Vector *next;
-};
-
-/* When V is on the free list, it's always treated as Lisp_Vectorlike_Free.  */
-
-#define NEXT_IN_FREE_LIST(v) ((struct Lisp_Vectorlike_Free *) v)->next
+  intptr_t i = XLI (v->contents[0]);
+  return (struct Lisp_Vector *) i;
+}
+static void
+set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
+{
+  v->contents[0] = XIL ((intptr_t) next);
+}
 
 /* Common shortcut to setup vector on a free list.  */
 
@@ -2633,7 +2636,7 @@ struct Lisp_Vectorlike_Free
     eassert ((nbytes) % roundup_size == 0);            \
     (tmp) = VINDEX (nbytes);                           \
     eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX);      \
-    NEXT_IN_FREE_LIST (v) = vector_free_lists[tmp];    \
+    set_next_in_free_list (v, vector_free_lists[tmp]); \
     vector_free_lists[tmp] = (v);                      \
     total_free_vector_slots += (nbytes) / word_size;   \
   } while (0)
@@ -2730,7 +2733,7 @@ allocate_vector_from_block (size_t nbytes)
   if (vector_free_lists[index])
     {
       vector = vector_free_lists[index];
-      vector_free_lists[index] = NEXT_IN_FREE_LIST (vector);
+      vector_free_lists[index] = next_in_free_list (vector);
       total_free_vector_slots -= nbytes / word_size;
       return vector;
     }
@@ -2744,7 +2747,7 @@ allocate_vector_from_block (size_t nbytes)
       {
        /* This vector is larger than requested.  */
        vector = vector_free_lists[index];
-       vector_free_lists[index] = NEXT_IN_FREE_LIST (vector);
+       vector_free_lists[index] = next_in_free_list (vector);
        total_free_vector_slots -= nbytes / word_size;
 
        /* Excess bytes are used for the smaller vector,