summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-04-25 00:14:46 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-04-25 00:14:46 -0700
commiteab3844f965646b62e242aa622754b86d1fd3444 (patch)
tree10246105e5facc5d61ccf797dfa05debdb1877c1
parent0df1eac54fdf82a80a7611fe421d94a23ebd4a0a (diff)
downloademacs-eab3844f965646b62e242aa622754b86d1fd3444.tar.gz
lisp.h: Fix a problem with aliasing and vector headers.
GCC 4.6.0 optimizes based on type-based alias analysis. For example, if b is of type struct buffer * and v of type struct Lisp_Vector *, then gcc -O2 was incorrectly assuming that &b->size != &v->size, and therefore "v->size = 1; b->size = 2; return v->size;" must therefore return 1. This assumption is incorrect for Emacs, since it type-puns struct Lisp_Vector * with many other types. To fix this problem, this patch adds a new type struct vector_header that documents the constraints on layout of vectors and pseudovectors, and helps optimizing compilers not get fooled by Emacs's type punning. It also adds the macros XSETTYPED_PVECTYPE XSETTYPED_PSEUDOVECTOR, TYPED_PSEUDOVECTORP, for similar reasons. * lisp.h (XVECTOR_SIZE): New convenience macro. All previous uses of XVECTOR (foo)->size replaced to use this macro, to avoid the hassle of writing XVECTOR (foo)->header.size. (XVECTOR_HEADER_SIZE): New macro, for use in XSETPSEUDOVECTOR. (XSETTYPED_PVECTYPE): New macro, specifying the name of the size member. (XSETPVECTYPE): Rewrite in terms of new macro. (XSETPVECTYPESIZE): New macro, specifying both type and size. This is a bit clearer, and further avoids the possibility of undesirable aliasing. (XSETTYPED_PSEUDOVECTOR): New macro, specifying the size. (XSETPSEUDOVECTOR): Rewrite in terms of XSETTYPED_PSEUDOVECTOR and XVECTOR_HEADER_SIZE. (XSETSUBR): Rewrite in terms of XSETTYPED_PSEUDOVECTOR and XSIZE, since Lisp_Subr is a special case (no "next" field). (ASIZE): Rewrite in terms of XVECTOR_SIZE. (struct vector_header): New type. (TYPED_PSEUDOVECTORP): New macro, also specifying the C type of the object, to help avoid aliasing. (PSEUDOVECTORP): Rewrite in terms of TYPED_PSEUDOVECTORP. (SUBRP): Likewise, since Lisp_Subr is a special case. * lisp.h (struct Lisp_Vector, struct Lisp_Char_Table): (struct Lisp_Sub_Char_Table, struct Lisp_Bool_Vector): (struct Lisp_Hash_Table): Combine first two members into a single struct vector_header member. All uses of "size" and "next" members changed to be "header.size" and "header.next". * buffer.h (struct buffer): Likewise. * font.h (struct font_spec, struct font_entity, struct font): Likewise. * frame.h (struct frame): Likewise. * process.h (struct Lisp_Process): Likewise. * termhooks.h (struct terminal): Likewise. * window.c (struct save_window_data, struct saved_window): Likewise. * window.h (struct window): Likewise. * alloc.c (allocate_buffer, Fmake_bool_vector, allocate_pseudovector): Use XSETPVECTYPESIZE, not XSETPVECTYPE, to avoid aliasing problems. * buffer.c (init_buffer_once): Likewise. * lread.c (defsubr): Use XSETTYPED_PVECTYPE, since Lisp_Subr is a special case. * process.c (Fformat_network_address): Use local var for size, for brevity.
-rw-r--r--src/ChangeLog55
-rw-r--r--src/alloc.c63
-rw-r--r--src/buffer.c18
-rw-r--r--src/buffer.h7
-rw-r--r--src/bytecode.c2
-rw-r--r--src/callint.c2
-rw-r--r--src/ccl.c2
-rw-r--r--src/character.c4
-rw-r--r--src/chartab.c2
-rw-r--r--src/coding.c2
-rw-r--r--src/composite.c6
-rw-r--r--src/data.c8
-rw-r--r--src/dispnew.c10
-rw-r--r--src/disptab.h3
-rw-r--r--src/doc.c2
-rw-r--r--src/fns.c10
-rw-r--r--src/font.c2
-rw-r--r--src/font.h9
-rw-r--r--src/frame.h3
-rw-r--r--src/fringe.c2
-rw-r--r--src/image.c4
-rw-r--r--src/indent.c12
-rw-r--r--src/keyboard.c38
-rw-r--r--src/keymap.c10
-rw-r--r--src/lisp.h73
-rw-r--r--src/lread.c22
-rw-r--r--src/minibuf.c6
-rw-r--r--src/print.c10
-rw-r--r--src/process.c15
-rw-r--r--src/process.h6
-rw-r--r--src/syntax.c4
-rw-r--r--src/termhooks.h6
-rw-r--r--src/w32font.c3
-rw-r--r--src/w32menu.c8
-rw-r--r--src/window.c14
-rw-r--r--src/window.h7
-rw-r--r--src/xdisp.c10
-rw-r--r--src/xfaces.c2
-rw-r--r--src/xmenu.c6
-rw-r--r--src/xselect.c16
40 files changed, 274 insertions, 210 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e6a9f9c69fb..e1548e9a094 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,58 @@
+2011-04-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ lisp.h: Fix a problem with aliasing and vector headers.
+ GCC 4.6.0 optimizes based on type-based alias analysis. For
+ example, if b is of type struct buffer * and v of type struct
+ Lisp_Vector *, then gcc -O2 was incorrectly assuming that &b->size
+ != &v->size, and therefore "v->size = 1; b->size = 2; return
+ v->size;" must therefore return 1. This assumption is incorrect
+ for Emacs, since it type-puns struct Lisp_Vector * with many other
+ types. To fix this problem, this patch adds a new type struct
+ vector_header that documents the constraints on layout of vectors
+ and pseudovectors, and helps optimizing compilers not get fooled
+ by Emacs's type punning. It also adds the macros XSETTYPED_PVECTYPE
+ XSETTYPED_PSEUDOVECTOR, TYPED_PSEUDOVECTORP, for similar reasons.
+ * lisp.h (XVECTOR_SIZE): New convenience macro. All previous uses of
+ XVECTOR (foo)->size replaced to use this macro, to avoid the hassle
+ of writing XVECTOR (foo)->header.size.
+ (XVECTOR_HEADER_SIZE): New macro, for use in XSETPSEUDOVECTOR.
+ (XSETTYPED_PVECTYPE): New macro, specifying the name of the size
+ member.
+ (XSETPVECTYPE): Rewrite in terms of new macro.
+ (XSETPVECTYPESIZE): New macro, specifying both type and size.
+ This is a bit clearer, and further avoids the possibility of
+ undesirable aliasing.
+ (XSETTYPED_PSEUDOVECTOR): New macro, specifying the size.
+ (XSETPSEUDOVECTOR): Rewrite in terms of XSETTYPED_PSEUDOVECTOR
+ and XVECTOR_HEADER_SIZE.
+ (XSETSUBR): Rewrite in terms of XSETTYPED_PSEUDOVECTOR and XSIZE,
+ since Lisp_Subr is a special case (no "next" field).
+ (ASIZE): Rewrite in terms of XVECTOR_SIZE.
+ (struct vector_header): New type.
+ (TYPED_PSEUDOVECTORP): New macro, also specifying the C type of the
+ object, to help avoid aliasing.
+ (PSEUDOVECTORP): Rewrite in terms of TYPED_PSEUDOVECTORP.
+ (SUBRP): Likewise, since Lisp_Subr is a special case.
+ * lisp.h (struct Lisp_Vector, struct Lisp_Char_Table):
+ (struct Lisp_Sub_Char_Table, struct Lisp_Bool_Vector):
+ (struct Lisp_Hash_Table): Combine first two members into a single
+ struct vector_header member. All uses of "size" and "next" members
+ changed to be "header.size" and "header.next".
+ * buffer.h (struct buffer): Likewise.
+ * font.h (struct font_spec, struct font_entity, struct font): Likewise.
+ * frame.h (struct frame): Likewise.
+ * process.h (struct Lisp_Process): Likewise.
+ * termhooks.h (struct terminal): Likewise.
+ * window.c (struct save_window_data, struct saved_window): Likewise.
+ * window.h (struct window): Likewise.
+ * alloc.c (allocate_buffer, Fmake_bool_vector, allocate_pseudovector):
+ Use XSETPVECTYPESIZE, not XSETPVECTYPE, to avoid aliasing problems.
+ * buffer.c (init_buffer_once): Likewise.
+ * lread.c (defsubr): Use XSETTYPED_PVECTYPE, since Lisp_Subr is a
+ special case.
+ * process.c (Fformat_network_address): Use local var for size,
+ for brevity.
+
2011-04-24 Paul Eggert <eggert@cs.ucla.edu>
* bytecode.c (exec_byte_code): Don't use XVECTOR before CHECK_VECTOR.
diff --git a/src/alloc.c b/src/alloc.c
index dd27303428f..c9496ecf25c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -146,9 +146,9 @@ static pthread_mutex_t alloc_mutex;
#define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG)
#define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0)
-#define VECTOR_MARK(V) ((V)->size |= ARRAY_MARK_FLAG)
-#define VECTOR_UNMARK(V) ((V)->size &= ~ARRAY_MARK_FLAG)
-#define VECTOR_MARKED_P(V) (((V)->size & ARRAY_MARK_FLAG) != 0)
+#define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG)
+#define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG)
+#define VECTOR_MARKED_P(V) (((V)->header.size & ARRAY_MARK_FLAG) != 0)
/* Value is the number of bytes of S, a pointer to a struct Lisp_String.
Be careful during GC, because S->size contains the mark bit for
@@ -1055,9 +1055,9 @@ allocate_buffer (void)
struct buffer *b
= (struct buffer *) lisp_malloc (sizeof (struct buffer),
MEM_TYPE_BUFFER);
- b->size = ((sizeof (struct buffer) + sizeof (EMACS_INT) - 1)
- / sizeof (EMACS_INT));
- XSETPVECTYPE (b, PVEC_BUFFER);
+ XSETPVECTYPESIZE (b, PVEC_BUFFER,
+ ((sizeof (struct buffer) + sizeof (EMACS_INT) - 1)
+ / sizeof (EMACS_INT)));
return b;
}
@@ -2244,10 +2244,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
slot `size' of the struct Lisp_Bool_Vector. */
val = Fmake_vector (make_number (length_in_elts + 1), Qnil);
- /* Get rid of any bits that would cause confusion. */
- XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */
- /* Use XVECTOR (val) rather than `p' because p->size is not TRT. */
- XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR);
+ /* No Lisp_Object to trace in there. */
+ XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0);
p = XBOOL_VECTOR (val);
p->size = XFASTINT (length);
@@ -2814,7 +2812,7 @@ allocate_vectorlike (EMACS_INT len)
consing_since_gc += nbytes;
vector_cells_consed += len;
- p->next = all_vectors;
+ p->header.next.vector = all_vectors;
all_vectors = p;
MALLOC_UNBLOCK_INPUT;
@@ -2830,7 +2828,7 @@ struct Lisp_Vector *
allocate_vector (EMACS_INT nslots)
{
struct Lisp_Vector *v = allocate_vectorlike (nslots);
- v->size = nslots;
+ v->header.size = nslots;
return v;
}
@@ -2844,11 +2842,10 @@ allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag)
EMACS_INT i;
/* Only the first lisplen slots will be traced normally by the GC. */
- v->size = lisplen;
for (i = 0; i < lisplen; ++i)
v->contents[i] = Qnil;
- XSETPVECTYPE (v, tag); /* Add the appropriate tag. */
+ XSETPVECTYPESIZE (v, tag, lisplen);
return v;
}
@@ -4737,7 +4734,7 @@ make_pure_vector (EMACS_INT len)
p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike);
XSETVECTOR (new, p);
- XVECTOR (new)->size = len;
+ XVECTOR (new)->header.size = len;
return new;
}
@@ -4775,7 +4772,7 @@ Does not copy symbols. Copies strings without text properties. */)
register EMACS_INT i;
EMACS_INT size;
- size = XVECTOR (obj)->size;
+ size = XVECTOR_SIZE (obj);
if (size & PSEUDOVECTOR_FLAG)
size &= PSEUDOVECTOR_SIZE_MASK;
vec = XVECTOR (make_pure_vector (size));
@@ -4899,7 +4896,7 @@ returns nil, because real GC can't be done. */)
}
}
- nextb = nextb->next;
+ nextb = nextb->header.next.buffer;
}
}
@@ -5054,7 +5051,7 @@ returns nil, because real GC can't be done. */)
undo_list any more, we can finally mark the list. */
mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list));
- nextb = nextb->next;
+ nextb = nextb->header.next.buffer;
}
}
@@ -5228,7 +5225,7 @@ static size_t mark_object_loop_halt;
static void
mark_vectorlike (struct Lisp_Vector *ptr)
{
- register EMACS_UINT size = ptr->size;
+ register EMACS_UINT size = ptr->header.size;
register EMACS_UINT i;
eassert (!VECTOR_MARKED_P (ptr));
@@ -5251,7 +5248,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
static void
mark_char_table (struct Lisp_Vector *ptr)
{
- register EMACS_UINT size = ptr->size & PSEUDOVECTOR_SIZE_MASK;
+ register EMACS_UINT size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
register EMACS_UINT i;
eassert (!VECTOR_MARKED_P (ptr));
@@ -5364,7 +5361,7 @@ mark_object (Lisp_Object arg)
if (po != &buffer_defaults && po != &buffer_local_symbols)
{
struct buffer *b;
- for (b = all_buffers; b && b != po; b = b->next)
+ for (b = all_buffers; b && b != po; b = b->header.next)
;
if (b == NULL)
abort ();
@@ -5380,7 +5377,7 @@ mark_object (Lisp_Object arg)
recursion there. */
{
register struct Lisp_Vector *ptr = XVECTOR (obj);
- register EMACS_UINT size = ptr->size;
+ register EMACS_UINT size = ptr->header.size;
register EMACS_UINT i;
CHECK_LIVE (live_vector_p);
@@ -6012,10 +6009,10 @@ gc_sweep (void)
if (!VECTOR_MARKED_P (buffer))
{
if (prev)
- prev->next = buffer->next;
+ prev->header.next = buffer->header.next;
else
- all_buffers = buffer->next;
- next = buffer->next;
+ all_buffers = buffer->header.next.buffer;
+ next = buffer->header.next.buffer;
lisp_free (buffer);
buffer = next;
}
@@ -6023,7 +6020,7 @@ gc_sweep (void)
{
VECTOR_UNMARK (buffer);
UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer));
- prev = buffer, buffer = buffer->next;
+ prev = buffer, buffer = buffer->header.next.buffer;
}
}
@@ -6036,10 +6033,10 @@ gc_sweep (void)
if (!VECTOR_MARKED_P (vector))
{
if (prev)
- prev->next = vector->next;
+ prev->header.next = vector->header.next;
else
- all_vectors = vector->next;
- next = vector->next;
+ all_vectors = vector->header.next.vector;
+ next = vector->header.next.vector;
lisp_free (vector);
n_vectors--;
vector = next;
@@ -6048,11 +6045,11 @@ gc_sweep (void)
else
{
VECTOR_UNMARK (vector);
- if (vector->size & PSEUDOVECTOR_FLAG)
- total_vector_size += (PSEUDOVECTOR_SIZE_MASK & vector->size);
+ if (vector->header.size & PSEUDOVECTOR_FLAG)
+ total_vector_size += PSEUDOVECTOR_SIZE_MASK & vector->header.size;
else
- total_vector_size += vector->size;
- prev = vector, vector = vector->next;
+ total_vector_size += vector->header.size;
+ prev = vector, vector = vector->header.next.vector;
}
}
diff --git a/src/buffer.c b/src/buffer.c
index c649836adb8..6ced4fbae87 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -43,7 +43,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
struct buffer *current_buffer; /* the current buffer */
/* First buffer in chain of all buffers (in reverse order of creation).
- Threaded through ->next. */
+ Threaded through ->header.next. */
struct buffer *all_buffers;
@@ -359,7 +359,7 @@ even if it is dead. The return value is never nil. */)
b->prevent_redisplay_optimizations_p = 1;
/* Put this on the chain of all buffers including killed ones. */
- b->next = all_buffers;
+ b->header.next.buffer = all_buffers;
all_buffers = b;
/* An ordinary buffer normally doesn't need markers
@@ -588,7 +588,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
BVAR (b, width_table) = Qnil;
/* Put this on the chain of all buffers including killed ones. */
- b->next = all_buffers;
+ b->header.next.buffer = all_buffers;
all_buffers = b;
name = Fcopy_sequence (name);
@@ -1458,7 +1458,7 @@ with SIGHUP. */)
GCPRO1 (buffer);
- for (other = all_buffers; other; other = other->next)
+ for (other = all_buffers; other; other = other->header.next.buffer)
/* all_buffers contains dead buffers too;
don't re-kill them. */
if (other->base_buffer == b && !NILP (BVAR (other, name)))
@@ -2099,7 +2099,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
{ /* This is probably harder to make work. */
struct buffer *other;
- for (other = all_buffers; other; other = other->next)
+ for (other = all_buffers; other; other = other->header.next.buffer)
if (other->base_buffer == other_buffer
|| other->base_buffer == current_buffer)
error ("One of the buffers to swap has indirect buffers");
@@ -2476,7 +2476,7 @@ current buffer is cleared. */)
/* Copy this buffer's new multibyte status
into all of its indirect buffers. */
- for (other = all_buffers; other; other = other->next)
+ for (other = all_buffers; other; other = other->header.next.buffer)
if (other->base_buffer == current_buffer && !NILP (BVAR (other, name)))
{
BVAR (other, enable_multibyte_characters)
@@ -4178,7 +4178,7 @@ static int last_overlay_modification_hooks_used;
static void
add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
{
- int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
+ int oldsize = XVECTOR_SIZE (last_overlay_modification_hooks);
if (last_overlay_modification_hooks_used == oldsize)
last_overlay_modification_hooks = larger_vector
@@ -4973,9 +4973,9 @@ init_buffer_once (void)
buffer_local_symbols.text = &buffer_local_symbols.own_text;
BUF_INTERVALS (&buffer_defaults) = 0;
BUF_INTERVALS (&buffer_local_symbols) = 0;
- XSETPVECTYPE (&buffer_defaults, PVEC_BUFFER);
+ XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, 0);
XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
- XSETPVECTYPE (&buffer_local_symbols, PVEC_BUFFER);
+ XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, 0);
XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
/* Set up the default values of various buffer slots. */
diff --git a/src/buffer.h b/src/buffer.h
index 2963aa382ca..51b318218cc 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -499,14 +499,13 @@ struct buffer
Check out mark_buffer (alloc.c) to see why. */
- EMACS_UINT size;
-
- /* Next buffer, in chain of all buffers including killed buffers.
+ /* HEADER.NEXT is the next buffer, in chain of all buffers,
+ including killed buffers.
This chain is used only for garbage collection, in order to
collect killed buffers properly.
Note that vectors and most pseudovectors are all on one chain,
but buffers are on a separate chain of their own. */
- struct buffer *next;
+ struct vector_header header;
/* This structure holds the coordinates of the buffer contents
in ordinary buffers. In indirect buffers, this is not used. */
diff --git a/src/bytecode.c b/src/bytecode.c
index 3bbd8831633..839e0f7d54e 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -467,7 +467,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CHECK_NUMBER (maxdepth);
#ifdef BYTE_CODE_SAFE
- const_length = XVECTOR (vector)->size;
+ const_length = XVECTOR_SIZE (vector);
#endif
if (STRING_MULTIBYTE (bytestr))
diff --git a/src/callint.c b/src/callint.c
index e5ec3d7d931..95b193ad91a 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -293,7 +293,7 @@ invoke it. If KEYS is omitted or nil, the return value of
else
{
CHECK_VECTOR (keys);
- key_count = XVECTOR (keys)->size;
+ key_count = XVECTOR_SIZE (keys);
}
/* Save this now, since use of minibuffer will clobber it. */
diff --git a/src/ccl.c b/src/ccl.c
index 66e0f2c6169..83afd7bc800 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1903,7 +1903,7 @@ setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog)
if (! VECTORP (ccl_prog))
return -1;
vp = XVECTOR (ccl_prog);
- ccl->size = vp->size;
+ ccl->size = vp->header.size;
ccl->prog = vp->contents;
ccl->eof_ic = XINT (vp->contents[CCL_HEADER_EOF]);
ccl->buf_magnification = XINT (vp->contents[CCL_HEADER_BUF_MAG]);
diff --git a/src/character.c b/src/character.c
index 84eddeb2fc2..8afe02b4700 100644
--- a/src/character.c
+++ b/src/character.c
@@ -357,7 +357,7 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision,
{
val = DISP_CHAR_VECTOR (dp, c);
if (VECTORP (val))
- thiswidth = XVECTOR (val)->size;
+ thiswidth = XVECTOR_SIZE (val);
else
thiswidth = CHAR_WIDTH (c);
}
@@ -446,7 +446,7 @@ lisp_string_width (Lisp_Object string, int precision,
{
val = DISP_CHAR_VECTOR (dp, c);
if (VECTORP (val))
- thiswidth = XVECTOR (val)->size;
+ thiswidth = XVECTOR_SIZE (val);
else
thiswidth = CHAR_WIDTH (c);
}
diff --git a/src/chartab.c b/src/chartab.c
index eb72d973c87..2f40ceee6ce 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -146,7 +146,7 @@ Lisp_Object
copy_char_table (Lisp_Object table)
{
Lisp_Object copy;
- int size = XCHAR_TABLE (table)->size & PSEUDOVECTOR_SIZE_MASK;
+ int size = XCHAR_TABLE (table)->header.size & PSEUDOVECTOR_SIZE_MASK;
int i;
copy = Fmake_vector (make_number (size), Qnil);
diff --git a/src/coding.c b/src/coding.c
index 38e41e7a99e..efe4a7c34a1 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7125,7 +7125,7 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
components = COMPOSITION_COMPONENTS (prop);
if (VECTORP (components))
{
- len = XVECTOR (components)->size;
+ len = XVECTOR_SIZE (components);
for (i = 0; i < len; i++)
*buf++ = XINT (AREF (components, i));
}
diff --git a/src/composite.c b/src/composite.c
index fab7cb86ba8..aa6090084a0 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -293,7 +293,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
}
else if (VECTORP (components) || CONSP (components))
{
- EMACS_UINT len = XVECTOR (key)->size;
+ EMACS_UINT len = XVECTOR_SIZE (key);
/* The number of elements should be odd. */
if ((len % 2) == 0)
@@ -326,8 +326,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
: COMPOSITION_WITH_RULE_ALTCHARS));
cmp->hash_index = hash_index;
glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
- ? (XVECTOR (key)->size + 1) / 2
- : XVECTOR (key)->size);
+ ? (XVECTOR_SIZE (key) + 1) / 2
+ : XVECTOR_SIZE (key));
cmp->glyph_len = glyph_len;
cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
cmp->font = NULL;
diff --git a/src/data.c b/src/data.c
index 4e81c80d0ed..68ea503d619 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1389,7 +1389,7 @@ for this variable. */)
{
struct buffer *b;
- for (b = all_buffers; b; b = b->next)
+ for (b = all_buffers; b; b = b->header.next.buffer)
if (!PER_BUFFER_VALUE_P (b, idx))
PER_BUFFER_VALUE (b, offset) = value;
}
@@ -2093,9 +2093,9 @@ or a byte-code object. IDX starts at 0. */)
{
int size = 0;
if (VECTORP (array))
- size = XVECTOR (array)->size;
+ size = XVECTOR_SIZE (array);
else if (COMPILEDP (array))
- size = XVECTOR (array)->size & PSEUDOVECTOR_SIZE_MASK;
+ size = XVECTOR_SIZE (array) & PSEUDOVECTOR_SIZE_MASK;
else
wrong_type_argument (Qarrayp, array);
@@ -2120,7 +2120,7 @@ bool-vector. IDX starts at 0. */)
if (VECTORP (array))
{
- if (idxval < 0 || idxval >= XVECTOR (array)->size)
+ if (idxval < 0 || idxval >= XVECTOR_SIZE (array))
args_out_of_range (array, idx);
XVECTOR (array)->contents[idxval] = newelt;
}
diff --git a/src/dispnew.c b/src/dispnew.c
index 5b8eaf4fa34..4b77040c266 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6073,7 +6073,7 @@ pass nil for VARIABLE. */)
state = frame_and_buffer_state;
vecp = XVECTOR (state)->contents;
- end = vecp + XVECTOR (state)->size;
+ end = vecp + XVECTOR_SIZE (state);
FOR_EACH_FRAME (tail, frame)
{
@@ -6124,8 +6124,8 @@ pass nil for VARIABLE. */)
/* Reallocate the vector if data has grown to need it,
or if it has shrunk a lot. */
if (! VECTORP (state)
- || n > XVECTOR (state)->size
- || n + 20 < XVECTOR (state)->size / 2)
+ || n > XVECTOR_SIZE (state)
+ || n + 20 < XVECTOR_SIZE (state) / 2)
/* Add 20 extra so we grow it less often. */
{
state = Fmake_vector (make_number (n + 20), Qlambda);
@@ -6155,11 +6155,11 @@ pass nil for VARIABLE. */)
/* Fill up the vector with lambdas (always at least one). */
*vecp++ = Qlambda;
while (vecp - XVECTOR (state)->contents
- < XVECTOR (state)->size)
+ < XVECTOR_SIZE (state))
*vecp++ = Qlambda;
/* Make sure we didn't overflow the vector. */
if (vecp - XVECTOR (state)->contents
- > XVECTOR (state)->size)
+ > XVECTOR_SIZE (state))
abort ();
return Qt;
}
diff --git a/src/disptab.h b/src/disptab.h
index be611cb8a90..76fc586f137 100644
--- a/src/disptab.h
+++ b/src/disptab.h
@@ -54,7 +54,7 @@ extern Lisp_Object Qdisplay_table;
/* Return the current length of the GLYPH table,
or 0 if the table isn't currently valid. */
#define GLYPH_TABLE_LENGTH \
- ((VECTORP (Vglyph_table)) ? XVECTOR (Vglyph_table)->size : 0)
+ ((VECTORP (Vglyph_table)) ? XVECTOR_SIZE (Vglyph_table) : 0)
/* Return the current base (for indexing) of the GLYPH table,
or 0 if the table isn't currently valid. */
@@ -95,4 +95,3 @@ extern Lisp_Object Qdisplay_table;
#define SET_GLYPH_FROM_CHAR(glyph, c) \
SET_GLYPH (glyph, c, DEFAULT_FACE_ID)
-
diff --git a/src/doc.c b/src/doc.c
index 74e06cce6b3..8c84e045e76 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -787,7 +787,7 @@ a new string, without any text properties, is returned. */)
do_remap:
tem = Fwhere_is_internal (name, keymap, Qt, Qnil, Qnil);
- if (VECTORP (tem) && XVECTOR (tem)->size > 1
+ if (VECTORP (tem) && XVECTOR_SIZE (tem) > 1
&& EQ (AREF (tem, 0), Qremap) && SYMBOLP (AREF (tem, 1))
&& follow_remap)
{
diff --git a/src/fns.c b/src/fns.c
index 20190399f9a..a128b9292c6 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3681,9 +3681,9 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
struct Lisp_Vector *next;
h2 = allocate_hash_table ();
- next = h2->vec_next;
+ next = h2->header.next.vector;
memcpy (h2, h1, sizeof *h2);
- h2->vec_next = next;
+ h2->header.next.vector = next;
h2->key_and_value = Fcopy_sequence (h1->key_and_value);
h2->hash = Fcopy_sequence (h1->hash);
h2->next = Fcopy_sequence (h1->next);
@@ -4026,7 +4026,7 @@ sweep_weak_hash_tables (void)
marked = 0;
for (h = weak_hash_tables; h; h = h->next_weak)
{
- if (h->size & ARRAY_MARK_FLAG)
+ if (h->header.size & ARRAY_MARK_FLAG)
marked |= sweep_weak_table (h, 0);
}
}
@@ -4037,7 +4037,7 @@ sweep_weak_hash_tables (void)
{
next = h->next_weak;
- if (h->size & ARRAY_MARK_FLAG)
+ if (h->header.size & ARRAY_MARK_FLAG)
{
/* TABLE is marked as used. Sweep its contents. */
if (h->count > 0)
@@ -4153,7 +4153,7 @@ sxhash_bool_vector (Lisp_Object vec)
unsigned hash = XBOOL_VECTOR (vec)->size;
int i, n;
- n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->vector_size);
+ n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
for (i = 0; i < n; ++i)
hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
diff --git a/src/font.c b/src/font.c
index 2a8cf2e48a7..a393597e06c 100644
--- a/src/font.c
+++ b/src/font.c
@@ -253,7 +253,7 @@ font_intern_prop (const char *str, int len, int force_symbol)
/* The following code is copied from the function intern (in
lread.c), and modified to suite our purpose. */
obarray = Vobarray;
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || XVECTOR_SIZE (obarray) == 0)
obarray = check_obarray (obarray);
parse_str_as_multibyte ((unsigned char *) str, len, &nchars, &nbytes);
if (len == nchars || len != nbytes)
diff --git a/src/font.h b/src/font.h
index 7b43c2f99e7..b9ac80f2cda 100644
--- a/src/font.h
+++ b/src/font.h
@@ -254,8 +254,7 @@ extern Lisp_Object Qja, Qko;
struct font_spec
{
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
Lisp_Object props[FONT_SPEC_MAX];
};
@@ -263,8 +262,7 @@ struct font_spec
struct font_entity
{
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
Lisp_Object props[FONT_ENTITY_MAX];
};
@@ -277,8 +275,7 @@ struct font_entity
struct font
{
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
/* All Lisp_Object components must come first.
That ensures they are all aligned normally. */
diff --git a/src/frame.h b/src/frame.h
index 944a3270ae5..b1300484a7e 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -82,8 +82,7 @@ struct font_driver_list;
struct frame
{
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
/* All Lisp_Object components must come first.
That ensures they are all aligned normally. */
diff --git a/src/fringe.c b/src/fringe.c
index bc6b493584c..e910152effa 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1531,7 +1531,7 @@ If BITMAP already exists, the existing definition is replaced. */)
if (STRINGP (bits))
h = SCHARS (bits);
else if (VECTORP (bits))
- h = XVECTOR (bits)->size;
+ h = XVECTOR_SIZE (bits);
else
wrong_type_argument (Qsequencep, bits);
diff --git a/src/image.c b/src/image.c
index fb555725b82..2346bb002e3 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2359,7 +2359,7 @@ xbm_image_p (Lisp_Object object)
int i;
/* Number of elements of the vector must be >= height. */
- if (XVECTOR (data)->size < height)
+ if (XVECTOR_SIZE (data) < height)
return 0;
/* Each string or bool-vector in data must be large enough
@@ -8398,7 +8398,7 @@ gs_image_p (Lisp_Object object)
}
else if (VECTORP (tem))
{
- if (XVECTOR (tem)->size != 4)
+ if (XVECTOR_SIZE (tem) != 4)
return 0;
for (i = 0; i < 4; ++i)
if (!INTEGERP (XVECTOR (tem)->contents[i]))
diff --git a/src/indent.c b/src/indent.c
index 094f6dabd55..a5ac2ab1d0c 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -93,7 +93,7 @@ character_width (int c, struct Lisp_Char_Table *dp)
/* Everything can be handled by the display table, if it's
present and the element is right. */
if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
- return XVECTOR (elt)->size;
+ return XVECTOR_SIZE (elt);
/* Some characters are special. */
if (c == '\n' || c == '\t' || c == '\015')
@@ -121,7 +121,7 @@ disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *w
{
int i;
- if (widthtab->size != 256)
+ if (widthtab->header.size != 256)
abort ();
for (i = 0; i < 256; i++)
@@ -143,7 +143,7 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
if (!VECTORP (BVAR (buf, width_table)))
BVAR (buf, width_table) = Fmake_vector (make_number (256), make_number (0));
widthtab = XVECTOR (BVAR (buf, width_table));
- if (widthtab->size != 256)
+ if (widthtab->header.size != 256)
abort ();
for (i = 0; i < 256; i++)
@@ -284,7 +284,7 @@ skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Ob
else \
{ \
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
- width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \
+ width = XVECTOR_SIZE (DISP_CHAR_VECTOR (dp, ch)); \
else \
width = CHAR_WIDTH (ch); \
} \
@@ -766,7 +766,7 @@ string_display_width (string, beg, end)
c = *--ptr;
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
- col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
+ col += XVECTOR_SIZE (DISP_CHAR_VECTOR (dp, c));
else if (c >= 040 && c < 0177)
col++;
else if (c == '\n')
@@ -1127,7 +1127,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_
: !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
int selective_rlen
= (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
- ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
+ ? XVECTOR_SIZE (DISP_INVIS_VECTOR (dp)) : 0);
/* The next location where the `invisible' property changes, or an
overlay starts or ends. */
EMACS_INT next_boundary = from;
diff --git a/src/keyboard.c b/src/keyboard.c
index b0ae1b1868d..8c4f7bdf804 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -134,7 +134,7 @@ static Lisp_Object raw_keybuf;
static int raw_keybuf_count;
#define GROW_RAW_KEYBUF \
- if (raw_keybuf_count == XVECTOR (raw_keybuf)->size) \
+ if (raw_keybuf_count == XVECTOR_SIZE (raw_keybuf)) \
raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil) \
/* Number of elements of this_command_keys
@@ -2898,7 +2898,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
&& SCHARS (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c))
|| (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table))
- && XVECTOR (KVAR (current_kboard, Vkeyboard_translate_table))->size > (unsigned) XFASTINT (c))
+ && XVECTOR_SIZE (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c))
|| (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
&& CHARACTERP (c)))
{
@@ -4198,7 +4198,7 @@ timer_start_idle (void)
timer = XCAR (timers);
- if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+ if (!VECTORP (timer) || XVECTOR_SIZE (timer) != 8)
continue;
XVECTOR (timer)->contents[0] = Qnil;
}
@@ -4293,7 +4293,7 @@ timer_check_2 (void)
if (CONSP (timers))
{
timer = XCAR (timers);
- if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+ if (!VECTORP (timer) || XVECTOR_SIZE (timer) != 8)
{
timers = XCDR (timers);
continue;
@@ -4311,7 +4311,7 @@ timer_check_2 (void)
if (CONSP (idle_timers))
{
timer = XCAR (idle_timers);
- if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+ if (!VECTORP (timer) || XVECTOR_SIZE (timer) != 8)
{
idle_timers = XCDR (idle_timers);
continue;
@@ -5459,7 +5459,7 @@ make_lispy_event (struct input_event *event)
/* Find the menu bar item under `column'. */
item = Qnil;
items = FRAME_MENU_BAR_ITEMS (f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < XVECTOR_SIZE (items); i += 4)
{
Lisp_Object pos, string;
string = AREF (items, i + 1);
@@ -5652,7 +5652,7 @@ make_lispy_event (struct input_event *event)
Qmouse_click, Vlispy_mouse_stem,
NULL,
&mouse_syms,
- XVECTOR (mouse_syms)->size);
+ XVECTOR_SIZE (mouse_syms));
if (event->modifiers & drag_modifier)
return Fcons (head,
Fcons (start_pos,
@@ -5823,7 +5823,7 @@ make_lispy_event (struct input_event *event)
Qmouse_click,
Vlispy_mouse_stem,
NULL, &mouse_syms,
- XVECTOR (mouse_syms)->size);
+ XVECTOR_SIZE (mouse_syms));
return Fcons (head, Fcons (position, Qnil));
}
@@ -5943,7 +5943,7 @@ make_lispy_event (struct input_event *event)
Qmouse_click, Vlispy_mouse_stem,
NULL,
&mouse_syms,
- XVECTOR (mouse_syms)->size);
+ XVECTOR_SIZE (mouse_syms));
if (event->modifiers & drag_modifier)
return Fcons (head,
@@ -6422,7 +6422,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
else
{
if (! VECTORP (*symbol_table)
- || XVECTOR (*symbol_table)->size != table_size)
+ || XVECTOR_SIZE (*symbol_table) != table_size)
{
Lisp_Object size;
@@ -7479,7 +7479,7 @@ menu_bar_items (Lisp_Object old)
/* Add nil, nil, nil, nil at the end. */
{
int i = menu_bar_items_index;
- if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
+ if (i + 4 > XVECTOR_SIZE (menu_bar_items_vector))
menu_bar_items_vector =
larger_vector (menu_bar_items_vector, 2 * i, Qnil);
/* Add this item. */
@@ -7551,7 +7551,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
if (i == menu_bar_items_index)
{
/* If vector is too small, get a bigger one. */
- if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
+ if (i + 4 > XVECTOR_SIZE (menu_bar_items_vector))
menu_bar_items_vector = larger_vector (menu_bar_items_vector, 2 * i, Qnil);
/* Add this item. */
XVECTOR (menu_bar_items_vector)->contents[i++] = key;
@@ -8219,7 +8219,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
}
else if (EQ (ikey, QCimage)
&& (CONSP (value)
- || (VECTORP (value) && XVECTOR (value)->size == 4)))
+ || (VECTORP (value) && XVECTOR_SIZE (value) == 4)))
/* Value is either a single image specification or a vector
of 4 such specifications for the different button states. */
PROP (TOOL_BAR_ITEM_IMAGES) = value;
@@ -8323,10 +8323,10 @@ append_tool_bar_item (void)
/* Enlarge tool_bar_items_vector if necessary. */
if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS
- >= XVECTOR (tool_bar_items_vector)->size)
+ >= XVECTOR_SIZE (tool_bar_items_vector))
tool_bar_items_vector
= larger_vector (tool_bar_items_vector,
- 2 * XVECTOR (tool_bar_items_vector)->size, Qnil);
+ 2 * XVECTOR_SIZE (tool_bar_items_vector), Qnil);
/* Append entries from tool_bar_item_properties to the end of
tool_bar_items_vector. */
@@ -8648,7 +8648,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
}
/* Move past this element. */
- if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size)
+ if (idx >= 0 && idx + 1 >= XVECTOR_SIZE (vector))
/* Handle reaching end of dense table. */
idx = -1;
if (idx >= 0)
@@ -9926,7 +9926,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
/* Treat uppercase keys as shifted. */
|| (INTEGERP (key)
&& (KEY_TO_CHAR (key)
- < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->size)
+ < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->header.size)
&& uppercasep (KEY_TO_CHAR (key))))
{
Lisp_Object new_key
@@ -10292,7 +10292,7 @@ give to the command you invoke, if it asks for an argument. */)
this_single_command_key_start = 0;
keys = XVECTOR (saved_keys)->contents;
- for (i = 0; i < XVECTOR (saved_keys)->size; i++)
+ for (i = 0; i < XVECTOR_SIZE (saved_keys); i++)
add_command_key (keys[i]);
for (i = 0; i < SCHARS (function); i++)
@@ -10585,7 +10585,7 @@ KEEP-RECORD is non-nil. */)
if (NILP (keep_record))
{
- for (i = 0; i < XVECTOR (recent_keys)->size; ++i)
+ for (i = 0; i < XVECTOR_SIZE (recent_keys); ++i)
XVECTOR (recent_keys)->contents[i] = Qnil;
total_keys = 0;
recent_keys_index = 0;
diff --git a/src/keymap.c b/src/keymap.c
index 8713bcf1279..110447b19ff 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -359,7 +359,7 @@ Return PARENT. PARENT should be nil or another keymap. */)
XCDR (XCAR (list)));
if (VECTORP (XCAR (list)))
- for (i = 0; i < XVECTOR (XCAR (list))->size; i++)
+ for (i = 0; i < XVECTOR_SIZE (XCAR (list)); i++)
if (CONSP (XVECTOR (XCAR (list))->contents[i]))
fix_submap_inheritance (keymap, make_number (i),
XVECTOR (XCAR (list))->contents[i]);
@@ -2226,7 +2226,7 @@ spaces are put between sequence elements, etc. */)
if (STRINGP (list))
size = SCHARS (list);
else if (VECTORP (list))
- size = XVECTOR (list)->size;
+ size = XVECTOR_SIZE (list);
else if (CONSP (list))
size = XINT (Flength (list));
else
@@ -3125,7 +3125,7 @@ key binding\n\
elt = XCAR (list);
elt_prefix = Fcar (elt);
- if (XVECTOR (elt_prefix)->size >= 1)
+ if (XVECTOR_SIZE (elt_prefix) >= 1)
{
tem = Faref (elt_prefix, make_number (0));
if (EQ (tem, Qmenu_bar))
@@ -3168,7 +3168,7 @@ key binding\n\
/* If the sequence by which we reach this keymap is zero-length,
then the shadow map for this keymap is just SHADOW. */
if ((STRINGP (elt_prefix) && SCHARS (elt_prefix) == 0)
- || (VECTORP (elt_prefix) && XVECTOR (elt_prefix)->size == 0))
+ || (VECTORP (elt_prefix) && XVECTOR_SIZE (elt_prefix) == 0))
;
/* If the sequence by which we reach this keymap actually has
some elements, then the sequence's definition in SHADOW is
@@ -3592,7 +3592,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
if (CHAR_TABLE_P (vector))
stop = MAX_5_BYTE_CHAR + 1, to = MAX_CHAR + 1;
else
- stop = to = XVECTOR (vector)->size;
+ stop = to = XVECTOR_SIZE (vector);
for (i = from; ; i++)
{
diff --git a/src/lisp.h b/src/lisp.h
index 5bace90e53e..e717e7c5cdb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -554,6 +554,11 @@ extern Lisp_Object make_number (EMACS_INT);
#define XSYMBOL(a) (eassert (SYMBOLP(a)),(struct Lisp_Symbol *) XPNTR(a))
#define XFLOAT(a) (eassert (FLOATP(a)),(struct Lisp_Float *) XPNTR(a))
+/* Extract the size field of a vector or vector-like object. */
+
+#define XVECTOR_SIZE(a) (XVECTOR (a)->header.size + 0)
+#define XVECTOR_HEADER_SIZE(a) (((struct vector_header *) XPNTR (a))->size + 0)
+
/* Misc types. */
#define XMISC(a) ((union Lisp_Misc *) XPNTR(a))
@@ -601,17 +606,24 @@ extern Lisp_Object make_number (EMACS_INT);
/* Pseudovector types. */
-#define XSETPVECTYPE(v,code) ((v)->size |= PSEUDOVECTOR_FLAG | (code))
+#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE(v, header.size, code)
+#define XSETTYPED_PVECTYPE(v, size_member, code) \
+ ((v)->size_member |= PSEUDOVECTOR_FLAG | (code))
+#define XSETPVECTYPESIZE(v, code, sizeval) \
+ ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval))
#define XSETPSEUDOVECTOR(a, b, code) \
+ XSETTYPED_PSEUDOVECTOR(a, b, XVECTOR_HEADER_SIZE (a), code)
+#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
(XSETVECTOR (a, b), \
- eassert ((XVECTOR (a)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
+ eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
== (PSEUDOVECTOR_FLAG | (code))))
#define XSETWINDOW_CONFIGURATION(a, b) \
(XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
-#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
+#define XSETSUBR(a, b) \
+ XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
@@ -621,7 +633,7 @@ extern Lisp_Object make_number (EMACS_INT);
/* Convenience macros for dealing with Lisp arrays. */
#define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX]
-#define ASIZE(ARRAY) XVECTOR ((ARRAY))->size
+#define ASIZE(ARRAY) XVECTOR_SIZE (ARRAY)
/* The IDX==IDX tries to detect when the macro argument is side-effecting. */
#define ASET(ARRAY, IDX, VAL) \
(eassert ((IDX) == (IDX)), \
@@ -778,10 +790,21 @@ struct Lisp_String
unsigned char *data;
};
-struct Lisp_Vector
+/* Header of vector-like objects. This type documents the constraints on
+ layout of vectors and pseudovectors, and helps optimizing compilers not get
+ fooled by Emacs's type punning. */
+struct vector_header
{
EMACS_UINT size;
- struct Lisp_Vector *next;
+ union {
+ struct buffer *buffer;
+ struct Lisp_Vector *vector;
+ } next;
+ };
+
+struct Lisp_Vector
+ {
+ struct vector_header header;
Lisp_Object contents[1];
};
@@ -817,7 +840,7 @@ struct Lisp_Vector
/* Return the number of "extra" slots in the char table CT. */
#define CHAR_TABLE_EXTRA_SLOTS(CT) \
- (((CT)->size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
+ (((CT)->header.size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
#ifdef __GNUC__
@@ -882,12 +905,11 @@ struct Lisp_Sub_Char_Table;
struct Lisp_Char_Table
{
- /* This is the vector's size field, which also holds the
+ /* HEADER.SIZE is the vector's size field, which also holds the
pseudovector type information. It holds the size, too.
The size counts the defalt, parent, purpose, ascii,
contents, and extras slots. */
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
/* This holds a default value,
which is used whenever the value for a specific character is nil. */
@@ -914,10 +936,9 @@ struct Lisp_Char_Table
struct Lisp_Sub_Char_Table
{
- /* This is the vector's size field, which also holds the
+ /* HEADER.SIZE is the vector's size field, which also holds the
pseudovector type information. It holds the size, too. */
- EMACS_INT size;
- struct Lisp_Vector *next;
+ struct vector_header header;
/* Depth of this sub char-table. It should be 1, 2, or 3. A sub
char-table of depth 1 contains 16 elements, and each element
@@ -936,10 +957,9 @@ struct Lisp_Sub_Char_Table
/* A boolvector is a kind of vectorlike, with contents are like a string. */
struct Lisp_Bool_Vector
{
- /* This is the vector's size field. It doesn't have the real size,
+ /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
just the subtype information. */
- EMACS_UINT vector_size;
- struct Lisp_Vector *next;
+ struct vector_header header;
/* This is the size in bits. */
EMACS_UINT size;
/* This contains the actual bits, packed into bytes. */
@@ -952,7 +972,7 @@ struct Lisp_Bool_Vector
This type is treated in most respects as a pseudovector,
but since we never dynamically allocate or free them,
- we don't need a next-vector field. */
+ we don't need a struct vector_header and its 'next' field. */
struct Lisp_Subr
{
@@ -1099,9 +1119,8 @@ struct Lisp_Symbol
struct Lisp_Hash_Table
{
- /* Vector fields. The hash table code doesn't refer to these. */
- EMACS_UINT size;
- struct Lisp_Vector *vec_next;
+ /* This is for Lisp; the hash table code does not refer to it. */
+ struct vector_header header;
/* Function used to compare keys. */
Lisp_Object test;
@@ -1202,7 +1221,7 @@ struct Lisp_Hash_Table
/* Value is the size of hash table H. */
-#define HASH_TABLE_SIZE(H) XVECTOR ((H)->next)->size
+#define HASH_TABLE_SIZE(H) XVECTOR_SIZE ((H)->next)
/* Default size for hash tables if not specified. */
@@ -1620,7 +1639,7 @@ typedef struct {
#define CONSP(x) (XTYPE ((x)) == Lisp_Cons)
#define FLOATP(x) (XTYPE ((x)) == Lisp_Float)
-#define VECTORP(x) (VECTORLIKEP (x) && !(XVECTOR (x)->size & PSEUDOVECTOR_FLAG))
+#define VECTORP(x) (VECTORLIKEP (x) && !(XVECTOR_SIZE (x) & PSEUDOVECTOR_FLAG))
#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
@@ -1633,8 +1652,14 @@ typedef struct {
/* True if object X is a pseudovector whose code is CODE. */
#define PSEUDOVECTORP(x, code) \
+ TYPED_PSEUDOVECTORP(x, vector_header, code)
+
+/* True if object X, with internal type struct T *, is a pseudovector whose
+ code is CODE. */
+#define TYPED_PSEUDOVECTORP(x, t, code) \
(VECTORLIKEP (x) \
- && (((XVECTOR (x)->size & (PSEUDOVECTOR_FLAG | (code)))) \
+ && (((((struct t *) XPNTR (x))->size \
+ & (PSEUDOVECTOR_FLAG | (code)))) \
== (PSEUDOVECTOR_FLAG | (code))))
/* Test for specific pseudovector types. */
@@ -1642,7 +1667,7 @@ typedef struct {
#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
-#define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR)
+#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
diff --git a/src/lread.c b/src/lread.c
index 3306c38e937..2ce2a4398a1 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2430,7 +2430,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
{
Lisp_Object tmp;
tmp = read_vector (readcharfun, 0);
- if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS)
+ if (XVECTOR_SIZE (tmp) < CHAR_TABLE_STANDARD_SLOTS)
error ("Invalid size char-table");
XSETPVECTYPE (XVECTOR (tmp), PVEC_CHAR_TABLE);
return tmp;
@@ -2449,7 +2449,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
depth = XINT (AREF (tmp, 0));
if (depth < 1 || depth > 3)
error ("Invalid depth in char-table");
- size = XVECTOR (tmp)->size - 2;
+ size = XVECTOR_SIZE (tmp) - 2;
if (chartab_size [depth] != size)
error ("Invalid size char-table");
XSETPVECTYPE (XVECTOR (tmp), PVEC_SUB_CHAR_TABLE);
@@ -2499,7 +2499,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
build them using function calls. */
Lisp_Object tmp;
tmp = read_vector (readcharfun, 1);
- return Fmake_byte_code (XVECTOR (tmp)->size,
+ return Fmake_byte_code (XVECTOR_SIZE (tmp),
XVECTOR (tmp)->contents);
}
if (c == '(')
@@ -3356,7 +3356,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag)
len = Flength (tem);
vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
- size = XVECTOR (vector)->size;
+ size = XVECTOR_SIZE (vector);
ptr = XVECTOR (vector)->contents;
for (i = 0; i < size; i++)
{
@@ -3621,7 +3621,7 @@ static int hash_string (const char *ptr, int len);
Lisp_Object
check_obarray (Lisp_Object obarray)
{
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || XVECTOR_SIZE (obarray) == 0)
{
/* If Vobarray is now invalid, force it to be valid. */
if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
@@ -3641,7 +3641,7 @@ intern (const char *str)
Lisp_Object obarray;
obarray = Vobarray;
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || XVECTOR_SIZE (obarray) == 0)
obarray = check_obarray (obarray);
tem = oblookup (obarray, str, len, len);
if (SYMBOLP (tem))
@@ -3657,7 +3657,7 @@ intern_c_string (const char *str)
Lisp_Object obarray;
obarray = Vobarray;
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || XVECTOR_SIZE (obarray) == 0)
obarray = check_obarray (obarray);
tem = oblookup (obarray, str, len, len);
if (SYMBOLP (tem))
@@ -3830,10 +3830,10 @@ oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_I
Lisp_Object bucket, tem;
if (!VECTORP (obarray)
- || (obsize = XVECTOR (obarray)->size) == 0)
+ || (obsize = XVECTOR_SIZE (obarray)) == 0)
{
obarray = check_obarray (obarray);
- obsize = XVECTOR (obarray)->size;
+ obsize = XVECTOR_SIZE (obarray);
}
/* This is sometimes needed in the middle of GC. */
obsize &= ~ARRAY_MARK_FLAG;
@@ -3881,7 +3881,7 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob
register int i;
register Lisp_Object tail;
CHECK_VECTOR (obarray);
- for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
+ for (i = XVECTOR_SIZE (obarray) - 1; i >= 0; i--)
{
tail = XVECTOR (obarray)->contents[i];
if (SYMBOLP (tail))
@@ -3961,7 +3961,7 @@ defsubr (struct Lisp_Subr *sname)
{
Lisp_Object sym;
sym = intern_c_string (sname->symbol_name);
- XSETPVECTYPE (sname, PVEC_SUBR);
+ XSETTYPED_PVECTYPE (sname, size, PVEC_SUBR);
XSETSUBR (XSYMBOL (sym)->function, sname);
}
diff --git a/src/minibuf.c b/src/minibuf.c
index 6316ba514b9..b73b2418cd6 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1227,7 +1227,7 @@ is used to further constrain the set of candidates. */)
if (type == obarray_table)
{
collection = check_obarray (collection);
- obsize = XVECTOR (collection)->size;
+ obsize = XVECTOR_SIZE (collection);
bucket = XVECTOR (collection)->contents[idx];
}
@@ -1490,7 +1490,7 @@ with a space are ignored unless STRING itself starts with a space. */)
if (type == 2)
{
collection = check_obarray (collection);
- obsize = XVECTOR (collection)->size;
+ obsize = XVECTOR_SIZE (collection);
bucket = XVECTOR (collection)->contents[idx];
}
@@ -1804,7 +1804,7 @@ the values STRING, PREDICATE and `lambda'. */)
if (completion_ignore_case && !SYMBOLP (tem))
{
- for (i = XVECTOR (collection)->size - 1; i >= 0; i--)
+ for (i = XVECTOR_SIZE (collection) - 1; i >= 0; i--)
{
tail = XVECTOR (collection)->contents[i];
if (SYMBOLP (tail))
diff --git a/src/print.c b/src/print.c
index 2c9aa9dfd85..8f559045f89 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1198,7 +1198,7 @@ print_preprocess (Lisp_Object obj)
goto loop;
case Lisp_Vectorlike:
- size = XVECTOR (obj)->size;
+ size = XVECTOR_SIZE (obj);
if (size & PSEUDOVECTOR_FLAG)
size &= PSEUDOVECTOR_SIZE_MASK;
for (i = 0; i < size; i++)
@@ -1786,7 +1786,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun);
PRINTCHAR (' ');
sprintf (buf, "%ld/%ld", (long) h->count,
- (long) XVECTOR (h->next)->size);
+ (long) XVECTOR_SIZE (h->next));
strout (buf, -1, -1, printcharfun);
}
sprintf (buf, " 0x%lx", (unsigned long) h);
@@ -1797,7 +1797,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
#s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
/* Always print the size. */
sprintf (buf, "#s(hash-table size %ld",
- (long) XVECTOR (h->next)->size);
+ (long) XVECTOR_SIZE (h->next));
strout (buf, -1, -1, printcharfun);
if (!NILP (h->test))
@@ -1909,7 +1909,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
}
else
{
- EMACS_INT size = XVECTOR (obj)->size;
+ EMACS_INT size = XVECTOR_SIZE (obj);
if (COMPILEDP (obj))
{
PRINTCHAR ('#');
@@ -2025,7 +2025,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
if (MISCP (obj))
sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj));
else if (VECTORLIKEP (obj))
- sprintf (buf, "(PVEC 0x%08lx)", (unsigned long) XVECTOR (obj)->size);
+ sprintf (buf, "(PVEC 0x%08lx)", (unsigned long) XVECTOR_SIZE (obj));
else
sprintf (buf, "(0x%02x)", (int) XTYPE (obj));
strout (buf, -1, -1, printcharfun);
diff --git a/src/process.c b/src/process.c
index f25d10dbd67..89a5f3e0386 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1188,25 +1188,26 @@ Returns nil if format of ADDRESS is invalid. */)
if (VECTORP (address)) /* AF_INET or AF_INET6 */
{
register struct Lisp_Vector *p = XVECTOR (address);
+ EMACS_UINT size = p->header.size;
Lisp_Object args[10];
int nargs, i;
- if (p->size == 4 || (p->size == 5 && !NILP (omit_port)))
+ if (size == 4 || (size == 5 && !NILP (omit_port)))
{
args[0] = build_string ("%d.%d.%d.%d");
nargs = 4;
}
- else if (p->size == 5)
+ else if (size == 5)
{
args[0] = build_string ("%d.%d.%d.%d:%d");
nargs = 5;
}
- else if (p->size == 8 || (p->size == 9 && !NILP (omit_port)))
+ else if (size == 8 || (size == 9 && !NILP (omit_port)))
{
args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
nargs = 8;
}
- else if (p->size == 9)
+ else if (size == 9)
{
args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d");
nargs = 9;
@@ -2064,13 +2065,13 @@ get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
if (VECTORP (address))
{
p = XVECTOR (address);
- if (p->size == 5)
+ if (p->header.size == 5)
{
*familyp = AF_INET;
return sizeof (struct sockaddr_in);
}
#ifdef AF_INET6
- else if (p->size == 9)
+ else if (p->header.size == 9)
{
*familyp = AF_INET6;
return sizeof (struct sockaddr_in6);
@@ -2089,7 +2090,7 @@ get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
struct sockaddr *sa;
*familyp = XINT (XCAR (address));
p = XVECTOR (XCDR (address));
- return p->size + sizeof (sa->sa_family);
+ return p->header.size + sizeof (sa->sa_family);
}
return 0;
}
diff --git a/src/process.h b/src/process.h
index 0348f211bb9..2fca7327a0c 100644
--- a/src/process.h
+++ b/src/process.h
@@ -29,13 +29,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* This structure records information about a subprocess
or network connection.
- Every field in this structure except for the first two
+ Every field in this structure except for the header
must be a Lisp_Object, for GC's sake. */
struct Lisp_Process
{
- EMACS_UINT size;
- struct Lisp_Vector *v_next;
+ struct vector_header header;
+
/* Name of subprocess terminal. */
Lisp_Object tty_name;
/* Name of this process */
diff --git a/src/syntax.c b/src/syntax.c
index 4be6b8db140..6b8e0c72b2b 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -979,7 +979,7 @@ text property. */)
break;
}
- if (val < XVECTOR (Vsyntax_code_object)->size && NILP (match))
+ if (val < XVECTOR_SIZE (Vsyntax_code_object) && NILP (match))
return XVECTOR (Vsyntax_code_object)->contents[val];
else
/* Since we can't use a shared object, let's make a new one. */
@@ -3370,7 +3370,7 @@ init_syntax_once (void)
/* Create objects which can be shared among syntax tables. */
Vsyntax_code_object = Fmake_vector (make_number (Smax), Qnil);
- for (i = 0; i < XVECTOR (Vsyntax_code_object)->size; i++)
+ for (i = 0; i < XVECTOR_SIZE (Vsyntax_code_object); i++)
XVECTOR (Vsyntax_code_object)->contents[i]
= Fcons (make_number (i), Qnil);
diff --git a/src/termhooks.h b/src/termhooks.h
index c6b1084f347..97dd87b4949 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -322,10 +322,8 @@ struct w32_display_info;
/* Terminal-local parameters. */
struct terminal
{
- /* The first two fields are really the header of a vector */
- /* The terminal code does not refer to them. */
- EMACS_UINT size;
- struct Lisp_Vector *vec_next;
+ /* This is for Lisp; the terminal code does not refer to it. */
+ struct vector_header header;
/* Parameter alist of this terminal. */
Lisp_Object param_alist;
diff --git a/src/w32font.c b/src/w32font.c
index d86107bc6d5..a9fa5256a43 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -165,7 +165,7 @@ intern_font_name (char * string)
/* The following code is copied from the function intern (in lread.c). */
obarray = Vobarray;
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || XVECTOR_SIZE (obarray) == 0)
obarray = check_obarray (obarray);
tem = oblookup (obarray, SDATA (str), len, len);
if (SYMBOLP (tem))
@@ -2581,4 +2581,3 @@ versions of Windows) characters. */);
w32font_driver.type = Qgdi;
register_font_driver (&w32font_driver, NULL);
}
-
diff --git a/src/w32menu.c b/src/w32menu.c
index f092ff87bf2..ef4f8d1485a 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -427,11 +427,11 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
menu_items = f->menu_bar_vector;
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
- submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
+ submenu_start = (int *) alloca (XVECTOR_SIZE (items) * sizeof (int *));
+ submenu_end = (int *) alloca (XVECTOR_SIZE (items) * sizeof (int *));
+ submenu_n_panes = (int *) alloca (XVECTOR_SIZE (items) * sizeof (int));
submenu_top_level_items
- = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+ = (int *) alloca (XVECTOR_SIZE (items) * sizeof (int *));
init_menu_items ();
for (i = 0; i < ASIZE (items); i += 4)
{
diff --git a/src/window.c b/src/window.c
index 5d059535614..92c7c57e213 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5794,8 +5794,7 @@ zero means top of window, negative means relative to bottom of window. */)
struct save_window_data
{
- EMACS_UINT size;
- struct Lisp_Vector *next_from_Lisp_Vector_struct;
+ struct vector_header header;
Lisp_Object selected_frame;
Lisp_Object current_window;
Lisp_Object current_buffer;
@@ -5817,10 +5816,7 @@ struct save_window_data
/* This is saved as a Lisp_Vector */
struct saved_window
{
- /* these first two must agree with struct Lisp_Vector in lisp.h */
- EMACS_UINT size;
- struct Lisp_Vector *next_from_Lisp_Vector_struct;
-
+ struct vector_header header;
Lisp_Object window;
Lisp_Object buffer, start, pointm, mark;
Lisp_Object left_col, top_line, total_cols, total_lines;
@@ -6001,7 +5997,7 @@ the return value is nil. Otherwise the value is t. */)
dead. */
delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f)));
- for (k = 0; k < saved_windows->size; k++)
+ for (k = 0; k < saved_windows->header.size; k++)
{
p = SAVED_WINDOW_N (saved_windows, k);
w = XWINDOW (p->window);
@@ -6884,10 +6880,10 @@ compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positi
return 0;
/* Verify that the two confis have the same number of windows. */
- if (sw1->size != sw2->size)
+ if (sw1->header.size != sw2->header.size)
return 0;
- for (i = 0; i < sw1->size; i++)
+ for (i = 0; i < sw1->header.size; i++)
{
struct saved_window *p1, *p2;
int w1_is_current, w2_is_current;
diff --git a/src/window.h b/src/window.h
index 65d554a5501..bdbe0e71cc7 100644
--- a/src/window.h
+++ b/src/window.h
@@ -88,10 +88,9 @@ struct cursor_pos
struct window
{
- /* The first two fields are really the header of a vector */
- /* The window code does not refer to them. */
- EMACS_UINT size;
- struct Lisp_Vector *vec_next;
+ /* This is for Lisp; the terminal code does not refer to it. */
+ struct vector_header header;
+
/* The frame this window is on. */
Lisp_Object frame;
/* t if this window is a minibuffer window. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 19fc36a90a3..63c2e5b8148 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3705,7 +3705,7 @@ setup_for_ellipsis (struct it *it, int len)
{
struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
}
else
{
@@ -5659,11 +5659,11 @@ get_next_display_element (struct it *it)
/* Return the first character from the display table
entry, if not empty. If empty, don't display the
current character. */
- if (v->size)
+ if (v->header.size)
{
it->dpvec_char_len = it->len;
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
it->current.dpvec_index = 0;
it->dpvec_face_id = -1;
it->saved_face_id = it->face_id;
@@ -18136,7 +18136,7 @@ display_menu_bar (struct window *w)
/* Display all items of the menu bar. */
items = FRAME_MENU_BAR_ITEMS (it.f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < XVECTOR_SIZE (items); i += 4)
{
Lisp_Object string;
@@ -24828,7 +24828,7 @@ on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
{
struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
Lisp_Object *poly = v->contents;
- int n = v->size;
+ int n = v->header.size;
int i;
int inside = 0;
Lisp_Object lx, ly;
diff --git a/src/xfaces.c b/src/xfaces.c
index fbed183522a..f20073f6e47 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1848,7 +1848,7 @@ the WIDTH times as wide as FACE on FRAME. */)
#define LFACEP(LFACE) \
(VECTORP (LFACE) \
- && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
+ && XVECTOR_SIZE (LFACE) == LFACE_VECTOR_SIZE \
&& EQ (AREF (LFACE, 0), Qface))
#endif
diff --git a/src/xmenu.c b/src/xmenu.c
index 938e5696b21..aac7fd43056 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1011,7 +1011,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
menu_items = f->menu_bar_vector;
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
- subitems = XVECTOR (items)->size / 4;
+ subitems = XVECTOR_SIZE (items) / 4;
submenu_start = (int *) alloca (subitems * sizeof (int *));
submenu_end = (int *) alloca (subitems * sizeof (int *));
submenu_n_panes = (int *) alloca (subitems * sizeof (int));
@@ -1097,7 +1097,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
/* Now GC cannot happen during the lifetime of the widget_value,
so it's safe to store data from a Lisp_String. */
wv = first_wv->contents;
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < XVECTOR_SIZE (items); i += 4)
{
Lisp_Object string;
string = XVECTOR (items)->contents[i + 1];
@@ -1123,7 +1123,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
first_wv = wv;
items = FRAME_MENU_BAR_ITEMS (f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < XVECTOR_SIZE (items); i += 4)
{
Lisp_Object string;
diff --git a/src/xselect.c b/src/xselect.c
index db00649f24d..27e2770f8ef 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -423,7 +423,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, in
int size;
int i;
pairs = XCDR (target_type);
- size = XVECTOR (pairs)->size;
+ size = XVECTOR_SIZE (pairs);
/* If the target is MULTIPLE, then target_type looks like
(MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ])
We modify the second element of each pair in the vector and
@@ -1261,12 +1261,12 @@ copy_multiple_data (obj)
return Fcons (XCAR (obj), copy_multiple_data (XCDR (obj)));
CHECK_VECTOR (obj);
- vec = Fmake_vector (size = XVECTOR (obj)->size, Qnil);
+ vec = Fmake_vector (size = XVECTOR_SIZE (obj), Qnil);
for (i = 0; i < size; i++)
{
Lisp_Object vec2 = XVECTOR (obj)->contents [i];
CHECK_VECTOR (vec2);
- if (XVECTOR (vec2)->size != 2)
+ if (XVECTOR_SIZE (vec2) != 2)
/* ??? Confusing error message */
signal_error ("Vectors must be of length 2", vec2);
XVECTOR (vec)->contents [i] = Fmake_vector (2, Qnil);
@@ -1878,7 +1878,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
/* This vector is an ATOM set */
{
if (NILP (type)) type = QATOM;
- *size_ret = XVECTOR (obj)->size;
+ *size_ret = XVECTOR_SIZE (obj);
*format_ret = 32;
*data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
for (i = 0; i < *size_ret; i++)
@@ -1893,7 +1893,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
/* This vector is an ATOM_PAIR set */
{
if (NILP (type)) type = QATOM_PAIR;
- *size_ret = XVECTOR (obj)->size;
+ *size_ret = XVECTOR_SIZE (obj);
*format_ret = 32;
*data_ret = (unsigned char *)
xmalloc ((*size_ret) * sizeof (Atom) * 2);
@@ -1901,7 +1901,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
if (VECTORP (XVECTOR (obj)->contents [i]))
{
Lisp_Object pair = XVECTOR (obj)->contents [i];
- if (XVECTOR (pair)->size != 2)
+ if (XVECTOR_SIZE (pair) != 2)
signal_error (
"Elements of the vector must be vectors of exactly two elements",
pair);
@@ -1923,7 +1923,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
/* This vector is an INTEGER set, or something like it */
{
int data_size = 2;
- *size_ret = XVECTOR (obj)->size;
+ *size_ret = XVECTOR_SIZE (obj);
if (NILP (type)) type = QINTEGER;
*format_ret = 16;
for (i = 0; i < *size_ret; i++)
@@ -1976,7 +1976,7 @@ clean_local_selection_data (Lisp_Object obj)
if (VECTORP (obj))
{
int i;
- int size = XVECTOR (obj)->size;
+ int size = XVECTOR_SIZE (obj);
Lisp_Object copy;
if (size == 1)
return clean_local_selection_data (XVECTOR (obj)->contents [0]);