>From 8776b3ccc765bff54b0186cadeba7c0a6fc60779 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 7 Sep 2018 09:17:25 -0700 Subject: [PATCH] Fix overenthusiastic header size check Problem reported by Eli Zaretskii in: https://lists.gnu.org/r/emacs-devel/2018-09/msg00222.html * doc/lispref/internals.texi (Garbage Collection): Document vector sizes and slot counts more accurately. * src/lisp.h: Omit header_size sanity check that was too picky. Add some less-picky checks. --- doc/lispref/internals.texi | 4 +++- src/lisp.h | 26 +++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 3fe28446ea..d42e2444e6 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -382,7 +382,7 @@ Garbage Collection The total size of all string data in bytes. @item vector-size -Internal size of a vector header, i.e., @code{sizeof (struct Lisp_Vector)}. +Size in bytes of a vector of length 1, including its header. @item used-vectors The number of vector headers allocated from the vector blocks. @@ -392,6 +392,8 @@ Garbage Collection @item used-slots The number of slots in all used vectors. +Slot counts might include some or all overhead from vector headers, +depending on the platform. @item free-slots The number of free slots in all vector blocks. diff --git a/src/lisp.h b/src/lisp.h index 7e365e8f47..56623a75f7 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1619,7 +1619,16 @@ struct Lisp_Bool_Vector } GCALIGNED_STRUCT; /* Some handy constants for calculating sizes - and offsets, mostly of vectorlike objects. */ + and offsets, mostly of vectorlike objects. + + The garbage collector assumes that the initial part of any struct + that starts with a union vectorlike_header followed by N + Lisp_Objects (some possibly in arrays and/or a trailing flexible + array) will be laid out like a struct Lisp_Vector with N + Lisp_Objects. This assumption is true in practice on known Emacs + targets even though the C standard does not guarantee it. This + header contains a few sanity checks that should suffice to detect + violations of this assumption on plausible practical hosts. */ enum { @@ -1627,7 +1636,6 @@ enum bool_header_size = offsetof (struct Lisp_Bool_Vector, data), word_size = sizeof (Lisp_Object) }; -verify (header_size == sizeof (union vectorlike_header)); /* The number of data words and bytes in a bool vector with SIZE bits. */ @@ -1989,6 +1997,13 @@ enum char_table_specials SUB_CHAR_TABLE_OFFSET = PSEUDOVECSIZE (struct Lisp_Sub_Char_Table, contents) }; +/* Sanity-check pseudovector layout. */ +verify (offsetof (struct Lisp_Char_Table, defalt) == header_size); +verify (offsetof (struct Lisp_Char_Table, extras) + == header_size + CHAR_TABLE_STANDARD_SLOTS * sizeof (Lisp_Object)); +verify (offsetof (struct Lisp_Sub_Char_Table, contents) + == header_size + SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object)); + /* Return the number of "extra" slots in the char table CT. */ INLINE int @@ -1998,11 +2013,6 @@ CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct) - CHAR_TABLE_STANDARD_SLOTS); } -/* Make sure that sub char-table contents slot is where we think it is. */ -verify (offsetof (struct Lisp_Sub_Char_Table, contents) - == (offsetof (struct Lisp_Vector, contents) - + SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object))); - /* Save and restore the instruction and environment pointers, without affecting the signal mask. */ @@ -2216,6 +2226,8 @@ struct Lisp_Hash_Table struct Lisp_Hash_Table *next_weak; } GCALIGNED_STRUCT; +/* Sanity-check pseudovector layout. */ +verify (offsetof (struct Lisp_Hash_Table, weak) == header_size); INLINE bool HASH_TABLE_P (Lisp_Object a) -- 2.17.1