From 36372bf93fc75b5f85d04007268e98840d1699c5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 17 Apr 2011 21:41:29 -0700 Subject: [PATCH] * alloc.c: Remove unportable assumptions about struct layout. (SDATA_SELECTOR, SDATA_DATA_OFFSET): New macros. (SDATA_OF_STRING, SDATA_SIZE, allocate_string_data): (allocate_vectorlike, make_pure_vector): Use the new macros, plus offsetof, to remove unportable assumptions about struct layout. These assumptions hold on all porting targets that I know of, but they are not guaranteed, they're easy to remove, and removing them makes further changes easier. --- src/ChangeLog | 9 +++++++++ src/alloc.c | 32 +++++++++++++------------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 81053d74480..b7a4a6701e0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,14 @@ 2011-04-18 Paul Eggert + * alloc.c: Remove unportable assumptions about struct layout. + (SDATA_SELECTOR, SDATA_DATA_OFFSET): New macros. + (SDATA_OF_STRING, SDATA_SIZE, allocate_string_data): + (allocate_vectorlike, make_pure_vector): Use the new macros, + plus offsetof, to remove unportable assumptions about struct layout. + These assumptions hold on all porting targets that I know of, but + they are not guaranteed, they're easy to remove, and removing them + makes further changes easier. + * alloc.c (BLOCK BYTES): Fix typo by changing "ablock" to "ablocks". This doesn't fix a bug but makes the code clearer. (string_overrun_cookie): Now const. Use initializers that diff --git a/src/alloc.c b/src/alloc.c index 2d1c8ffe70b..fbc075be3be 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1517,6 +1517,7 @@ struct sdata #define SDATA_NBYTES(S) (S)->nbytes #define SDATA_DATA(S) (S)->data +#define SDATA_SELECTOR(member) member #else /* not GC_CHECK_STRING_BYTES */ @@ -1531,8 +1532,11 @@ struct sdata #define SDATA_NBYTES(S) (S)->u.nbytes #define SDATA_DATA(S) (S)->u.data +#define SDATA_SELECTOR(member) u.member #endif /* not GC_CHECK_STRING_BYTES */ + +#define SDATA_DATA_OFFSET offsetof (struct sdata, SDATA_SELECTOR (data)) }; @@ -1608,18 +1612,7 @@ static EMACS_INT total_string_size; a pointer to the `u.data' member of its sdata structure; the structure starts at a constant offset in front of that. */ -#ifdef GC_CHECK_STRING_BYTES - -#define SDATA_OF_STRING(S) \ - ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *) \ - - sizeof (EMACS_INT))) - -#else /* not GC_CHECK_STRING_BYTES */ - -#define SDATA_OF_STRING(S) \ - ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *))) - -#endif /* not GC_CHECK_STRING_BYTES */ +#define SDATA_OF_STRING(S) ((struct sdata *) ((S)->data - SDATA_DATA_OFFSET)) #ifdef GC_CHECK_STRING_OVERRUN @@ -1643,17 +1636,16 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = #ifdef GC_CHECK_STRING_BYTES #define SDATA_SIZE(NBYTES) \ - ((sizeof (struct Lisp_String *) \ + ((SDATA_DATA_OFFSET \ + (NBYTES) + 1 \ - + sizeof (EMACS_INT) \ + sizeof (EMACS_INT) - 1) \ & ~(sizeof (EMACS_INT) - 1)) #else /* not GC_CHECK_STRING_BYTES */ #define SDATA_SIZE(NBYTES) \ - ((sizeof (struct Lisp_String *) \ - + (NBYTES) + 1 \ + ((SDATA_DATA_OFFSET \ + + max (NBYTES, sizeof (EMACS_INT) - 1) + 1 \ + sizeof (EMACS_INT) - 1) \ & ~(sizeof (EMACS_INT) - 1)) @@ -1877,7 +1869,7 @@ allocate_string_data (struct Lisp_String *s, if (nbytes > LARGE_STRING_BYTES) { - size_t size = sizeof *b - sizeof (struct sdata) + needed; + size_t size = offsetof (struct sblock, first_data) + needed; #ifdef DOUG_LEA_MALLOC /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed @@ -2807,7 +2799,8 @@ allocate_vectorlike (EMACS_INT len) /* This gets triggered by code which I haven't bothered to fix. --Stef */ /* eassert (!handling_signal); */ - nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; + nbytes = (offsetof (struct Lisp_Vector, contents) + + len * sizeof p->contents[0]); p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); #ifdef DOUG_LEA_MALLOC @@ -4735,7 +4728,8 @@ make_pure_vector (EMACS_INT len) { Lisp_Object new; struct Lisp_Vector *p; - size_t size = sizeof *p + (len - 1) * sizeof (Lisp_Object); + size_t size = (offsetof (struct Lisp_Vector, contents) + + len * sizeof (Lisp_Object)); p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike); XSETVECTOR (new, p); -- 2.39.2