diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-26 12:14:07 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-26 12:14:07 -0700 |
commit | aa0b008761ca665ee64bc65a7208478a6bb69fe2 (patch) | |
tree | ba03e49fd2fe86c6adfd62bda42cf07b2d10327e | |
parent | 69e9b5a37cf64ead4e10688063eef705744332bb (diff) | |
download | emacs-aa0b008761ca665ee64bc65a7208478a6bb69fe2.tar.gz |
* lisp.h: Add comments about struct vectorlike_header.
-rw-r--r-- | src/lisp.h | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/lisp.h b/src/lisp.h index 65b783f7b46..625027769cf 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -606,6 +606,8 @@ extern Lisp_Object make_number (EMACS_INT); ((v)->size_member |= PSEUDOVECTOR_FLAG | (code)) #define XSETPVECTYPESIZE(v, code, sizeval) \ ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval)) + +/* The cast to struct vectorlike_header * avoids aliasing issues. */ #define XSETPSEUDOVECTOR(a, b, code) \ XSETTYPED_PSEUDOVECTOR(a, b, \ ((struct vectorlike_header *) XPNTR (a))->size, \ @@ -614,11 +616,13 @@ extern Lisp_Object make_number (EMACS_INT); (XSETVECTOR (a, b), \ 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)) +/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ #define XSETSUBR(a, b) \ XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) @@ -787,12 +791,21 @@ struct Lisp_String unsigned char *data; }; -/* 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. */ +/* Header of vector-like objects. This documents the layout constraints on + vectors and pseudovectors other than struct Lisp_Subr. It also prevents + compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR + and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, + because when two such pointers potentially alias, a compiler won't + incorrectly reorder loads and stores to their size fields. See + <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ struct vectorlike_header { EMACS_UINT size; + + /* Pointer to the next vector-like object. It is generally a buffer or a + Lisp_Vector alias, so for convenience it is a union instead of a + pointer: this way, one can write P->next.vector instead of ((struct + Lisp_Vector *) P->next). */ union { struct buffer *buffer; struct Lisp_Vector *vector; @@ -1647,7 +1660,8 @@ typedef struct { #define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj) #define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj) -/* True if object X is a pseudovector whose code is CODE. */ +/* True if object X is a pseudovector whose code is CODE. The cast to struct + vectorlike_header * avoids aliasing issues. */ #define PSEUDOVECTORP(x, code) \ TYPED_PSEUDOVECTORP(x, vectorlike_header, code) @@ -1664,6 +1678,7 @@ typedef struct { #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) +/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ #define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) |