Commit d55c12ed authored by Andreas Schwab's avatar Andreas Schwab
Browse files

Simplify enforcement of object address alignment

* lisp.h (struct Lisp_Symbol): Remove explicit padding.
(struct Lisp_Misc_Any): Likewise.
(struct Lisp_Free): Likewise.
* alloc.c (union aligned_Lisp_Symbol): Define.
(SYMBOL_BLOCK_SIZE, struct symbol_block): Use union
aligned_Lisp_Symbol instead of struct Lisp_Symbol.
(union aligned_Lisp_Misc): Define.
(MARKER_BLOCK_SIZE, struct marker_block): Use union
aligned_Lisp_Misc instead of union Lisp_Misc.
(Fmake_symbol, allocate_misc, gc_sweep): Adjust
parent 7a76850c
2012-04-15 Andreas Schwab <schwab@linux-m68k.org>
* lisp.h (struct Lisp_Symbol): Remove explicit padding.
(struct Lisp_Misc_Any): Likewise.
(struct Lisp_Free): Likewise.
* alloc.c (union aligned_Lisp_Symbol): Define.
(SYMBOL_BLOCK_SIZE, struct symbol_block): Use union
aligned_Lisp_Symbol instead of struct Lisp_Symbol.
(union aligned_Lisp_Misc): Define.
(MARKER_BLOCK_SIZE, struct marker_block): Use union
aligned_Lisp_Misc instead of union Lisp_Misc.
(Fmake_symbol, allocate_misc, gc_sweep): Adjust
2012-04-14 Paul Eggert <eggert@cs.ucla.edu> 2012-04-14 Paul Eggert <eggert@cs.ucla.edu>
Make GC_MAKE_GCPROS_NOOPS the default (Bug#9926). Make GC_MAKE_GCPROS_NOOPS the default (Bug#9926).
......
...@@ -3136,17 +3136,29 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT ...@@ -3136,17 +3136,29 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
Symbol Allocation Symbol Allocation
***********************************************************************/ ***********************************************************************/
/* Like struct Lisp_Symbol, but padded so that the size is a multiple
of the required alignment if LSB tags are used. */
union aligned_Lisp_Symbol
{
struct Lisp_Symbol s;
#ifdef USE_LSB_TAG
unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1)
& -(1 << GCTYPEBITS)];
#endif
};
/* Each symbol_block is just under 1020 bytes long, since malloc /* Each symbol_block is just under 1020 bytes long, since malloc
really allocates in units of powers of two and uses 4 bytes for its really allocates in units of powers of two and uses 4 bytes for its
own overhead. */ own overhead. */
#define SYMBOL_BLOCK_SIZE \ #define SYMBOL_BLOCK_SIZE \
((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol))
struct symbol_block struct symbol_block
{ {
/* Place `symbols' first, to preserve alignment. */ /* Place `symbols' first, to preserve alignment. */
struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
struct symbol_block *next; struct symbol_block *next;
}; };
...@@ -3202,7 +3214,7 @@ Its value and function definition are void, and its property list is nil. */) ...@@ -3202,7 +3214,7 @@ Its value and function definition are void, and its property list is nil. */)
symbol_block = new; symbol_block = new;
symbol_block_index = 0; symbol_block_index = 0;
} }
XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s);
symbol_block_index++; symbol_block_index++;
} }
...@@ -3230,16 +3242,28 @@ Its value and function definition are void, and its property list is nil. */) ...@@ -3230,16 +3242,28 @@ Its value and function definition are void, and its property list is nil. */)
Marker (Misc) Allocation Marker (Misc) Allocation
***********************************************************************/ ***********************************************************************/
/* Like union Lisp_Misc, but padded so that its size is a multiple of
the required alignment when LSB tags are used. */
union aligned_Lisp_Misc
{
union Lisp_Misc m;
#ifdef USE_LSB_TAG
unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1)
& -(1 << GCTYPEBITS)];
#endif
};
/* Allocation of markers and other objects that share that structure. /* Allocation of markers and other objects that share that structure.
Works like allocation of conses. */ Works like allocation of conses. */
#define MARKER_BLOCK_SIZE \ #define MARKER_BLOCK_SIZE \
((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc)) ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc))
struct marker_block struct marker_block
{ {
/* Place `markers' first, to preserve alignment. */ /* Place `markers' first, to preserve alignment. */
union Lisp_Misc markers[MARKER_BLOCK_SIZE]; union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE];
struct marker_block *next; struct marker_block *next;
}; };
...@@ -3284,7 +3308,7 @@ allocate_misc (void) ...@@ -3284,7 +3308,7 @@ allocate_misc (void)
marker_block_index = 0; marker_block_index = 0;
total_free_markers += MARKER_BLOCK_SIZE; total_free_markers += MARKER_BLOCK_SIZE;
} }
XSETMISC (val, &marker_block->markers[marker_block_index]); XSETMISC (val, &marker_block->markers[marker_block_index].m);
marker_block_index++; marker_block_index++;
} }
...@@ -6070,22 +6094,22 @@ gc_sweep (void) ...@@ -6070,22 +6094,22 @@ gc_sweep (void)
for (sblk = symbol_block; sblk; sblk = *sprev) for (sblk = symbol_block; sblk; sblk = *sprev)
{ {
int this_free = 0; int this_free = 0;
struct Lisp_Symbol *sym = sblk->symbols; union aligned_Lisp_Symbol *sym = sblk->symbols;
struct Lisp_Symbol *end = sym + lim; union aligned_Lisp_Symbol *end = sym + lim;
for (; sym < end; ++sym) for (; sym < end; ++sym)
{ {
/* Check if the symbol was created during loadup. In such a case /* Check if the symbol was created during loadup. In such a case
it might be pointed to by pure bytecode which we don't trace, it might be pointed to by pure bytecode which we don't trace,
so we conservatively assume that it is live. */ so we conservatively assume that it is live. */
int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); int pure_p = PURE_POINTER_P (XSTRING (sym->s.xname));
if (!sym->gcmarkbit && !pure_p) if (!sym->s.gcmarkbit && !pure_p)
{ {
if (sym->redirect == SYMBOL_LOCALIZED) if (sym->s.redirect == SYMBOL_LOCALIZED)
xfree (SYMBOL_BLV (sym)); xfree (SYMBOL_BLV (&sym->s));
sym->next = symbol_free_list; sym->s.next = symbol_free_list;
symbol_free_list = sym; symbol_free_list = &sym->s;
#if GC_MARK_STACK #if GC_MARK_STACK
symbol_free_list->function = Vdead; symbol_free_list->function = Vdead;
#endif #endif
...@@ -6095,8 +6119,8 @@ gc_sweep (void) ...@@ -6095,8 +6119,8 @@ gc_sweep (void)
{ {
++num_used; ++num_used;
if (!pure_p) if (!pure_p)
UNMARK_STRING (XSTRING (sym->xname)); UNMARK_STRING (XSTRING (sym->s.xname));
sym->gcmarkbit = 0; sym->s.gcmarkbit = 0;
} }
} }
...@@ -6108,7 +6132,7 @@ gc_sweep (void) ...@@ -6108,7 +6132,7 @@ gc_sweep (void)
{ {
*sprev = sblk->next; *sprev = sblk->next;
/* Unhook from the free list. */ /* Unhook from the free list. */
symbol_free_list = sblk->symbols[0].next; symbol_free_list = sblk->symbols[0].s.next;
lisp_free (sblk); lisp_free (sblk);
} }
else else
...@@ -6138,22 +6162,22 @@ gc_sweep (void) ...@@ -6138,22 +6162,22 @@ gc_sweep (void)
for (i = 0; i < lim; i++) for (i = 0; i < lim; i++)
{ {
if (!mblk->markers[i].u_any.gcmarkbit) if (!mblk->markers[i].m.u_any.gcmarkbit)
{ {
if (mblk->markers[i].u_any.type == Lisp_Misc_Marker) if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
unchain_marker (&mblk->markers[i].u_marker); unchain_marker (&mblk->markers[i].m.u_marker);
/* Set the type of the freed object to Lisp_Misc_Free. /* Set the type of the freed object to Lisp_Misc_Free.
We could leave the type alone, since nobody checks it, We could leave the type alone, since nobody checks it,
but this might catch bugs faster. */ but this might catch bugs faster. */
mblk->markers[i].u_marker.type = Lisp_Misc_Free; mblk->markers[i].m.u_marker.type = Lisp_Misc_Free;
mblk->markers[i].u_free.chain = marker_free_list; mblk->markers[i].m.u_free.chain = marker_free_list;
marker_free_list = &mblk->markers[i]; marker_free_list = &mblk->markers[i].m;
this_free++; this_free++;
} }
else else
{ {
num_used++; num_used++;
mblk->markers[i].u_any.gcmarkbit = 0; mblk->markers[i].m.u_any.gcmarkbit = 0;
} }
} }
lim = MARKER_BLOCK_SIZE; lim = MARKER_BLOCK_SIZE;
...@@ -6164,7 +6188,7 @@ gc_sweep (void) ...@@ -6164,7 +6188,7 @@ gc_sweep (void)
{ {
*mprev = mblk->next; *mprev = mblk->next;
/* Unhook from the free list. */ /* Unhook from the free list. */
marker_free_list = mblk->markers[0].u_free.chain; marker_free_list = mblk->markers[0].m.u_free.chain;
lisp_free (mblk); lisp_free (mblk);
} }
else else
......
...@@ -1134,8 +1134,6 @@ struct Lisp_Symbol ...@@ -1134,8 +1134,6 @@ struct Lisp_Symbol
special (with `defvar' etc), and shouldn't be lexically bound. */ special (with `defvar' etc), and shouldn't be lexically bound. */
unsigned declared_special : 1; unsigned declared_special : 1;
unsigned spacer : 23;
/* The symbol's name, as a Lisp string. /* The symbol's name, as a Lisp string.
The name "xname" is used to intentionally break code referring to The name "xname" is used to intentionally break code referring to
the old field "name" of type pointer to struct Lisp_String. */ the old field "name" of type pointer to struct Lisp_String. */
...@@ -1337,8 +1335,6 @@ struct Lisp_Misc_Any /* Supertype of all Misc types. */ ...@@ -1337,8 +1335,6 @@ struct Lisp_Misc_Any /* Supertype of all Misc types. */
ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_??? */ ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_??? */
unsigned gcmarkbit : 1; unsigned gcmarkbit : 1;
int spacer : 15; int spacer : 15;
/* Make it as long as "Lisp_Free without padding". */
void *fill;
}; };
struct Lisp_Marker struct Lisp_Marker
...@@ -1530,13 +1526,6 @@ struct Lisp_Free ...@@ -1530,13 +1526,6 @@ struct Lisp_Free
unsigned gcmarkbit : 1; unsigned gcmarkbit : 1;
int spacer : 15; int spacer : 15;
union Lisp_Misc *chain; union Lisp_Misc *chain;
#ifdef USE_LSB_TAG
/* Try to make sure that sizeof(Lisp_Misc) preserves TYPEBITS-alignment.
This assumes that Lisp_Marker is the largest of the alternatives and
that Lisp_Misc_Any has the same size as "Lisp_Free w/o padding". */
char padding[((((sizeof (struct Lisp_Marker) - 1) >> GCTYPEBITS) + 1)
<< GCTYPEBITS) - sizeof (struct Lisp_Misc_Any)];
#endif
}; };
/* To get the type field of a union Lisp_Misc, use XMISCTYPE. /* To get the type field of a union Lisp_Misc, use XMISCTYPE.
...@@ -1545,19 +1534,19 @@ struct Lisp_Free ...@@ -1545,19 +1534,19 @@ struct Lisp_Free
union Lisp_Misc union Lisp_Misc
{ {
struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */ struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */
struct Lisp_Free u_free; /* Includes padding to force alignment. */ struct Lisp_Free u_free;
struct Lisp_Marker u_marker; /* 5 */ struct Lisp_Marker u_marker;
struct Lisp_Overlay u_overlay; /* 5 */ struct Lisp_Overlay u_overlay;
struct Lisp_Save_Value u_save_value; /* 3 */ struct Lisp_Save_Value u_save_value;
}; };
union Lisp_Fwd union Lisp_Fwd
{ {
struct Lisp_Intfwd u_intfwd; /* 2 */ struct Lisp_Intfwd u_intfwd;
struct Lisp_Boolfwd u_boolfwd; /* 2 */ struct Lisp_Boolfwd u_boolfwd;
struct Lisp_Objfwd u_objfwd; /* 2 */ struct Lisp_Objfwd u_objfwd;
struct Lisp_Buffer_Objfwd u_buffer_objfwd; /* 2 */ struct Lisp_Buffer_Objfwd u_buffer_objfwd;
struct Lisp_Kboard_Objfwd u_kboard_objfwd; /* 2 */ struct Lisp_Kboard_Objfwd u_kboard_objfwd;
}; };
/* Lisp floating point type */ /* Lisp floating point type */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment