Subject: Re: bug#15405: 24.3; #[] freezes emacs

From: Barry OReilly <[email-masked]>
Date: Wed, 25 Sep 2013 11:22:34 -0400

>From the code, I thought I could make the following change and have
zero vectors participate in the vector_free_lists.

--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2626,7 +2626,7 @@ verify (VECTOR_BLOCK_SIZE <= (1 <<
PSEUDOVECTOR_SIZE_BITS));

 /* Size of the minimal vector allocated from block.  */

-#define VBLOCK_BYTES_MIN vroundup_ct (header_size + sizeof (Lisp_Object))
+#define VBLOCK_BYTES_MIN vroundup_ct (header_size)

 /* Size of the largest vector allocated from block.  */

After debugging the subsequent core dumping, I found it doesn't work
because Lisp_Vector is defined by:

struct Lisp_Vector
  {
    struct vectorlike_header header;
    union {
      /* ...but sometimes there is also a pointer internally used in
     vector allocation code.  Usually you don't want to touch this.  */
      struct Lisp_Vector *next;

      /* We can't use FLEXIBLE_ARRAY_MEMBER here.  */
      Lisp_Object contents[1];
    } u;
  };

Without any special casing of zero vectors, the allocator calls
SETUP_ON_FREE_LIST for a zero vector and sets v->u.next. But for a
zero vector the allocator only allows enough memory for the header, so
setting the next pointer corrupts other memory.

Of course when a non zero vector is taken from the free list, the next
pointer is no longer needed and can be overridden by the contents.
Clever use of space.

Which of these solutions would be most palatable?
  - Allocate zero vectors as "large_vectors", but with appropriate
    renaming of "large".
  - Allocate separately as a MEM_TYPE_VECTORLIKE, maintain a list of
    zero_vectors for GC
  - Smuggle zero vectors on the vector_free_lists with same allocation
    size as a 1-vector