diff options
| author | Eli Zaretskii | 2011-05-09 05:59:23 -0400 |
|---|---|---|
| committer | Eli Zaretskii | 2011-05-09 05:59:23 -0400 |
| commit | 14fe7b530dc927a88169a841afc0cd806593dea8 (patch) | |
| tree | 510192ce4c22c74ffec5b97327ea5e4a03a5a66c /src/process.c | |
| parent | 6eea50c73be34e865dabf14cbd2d0e7c4f64e6a0 (diff) | |
| download | emacs-14fe7b530dc927a88169a841afc0cd806593dea8.tar.gz emacs-14fe7b530dc927a88169a841afc0cd806593dea8.zip | |
Backport revisions 2011-04-24T05:30:24Z!eggert@cs.ucla.edu..2011-04-25T19:40:22Z!eggert@cs.ucla.edu (inclusive) from trunk (bug#8623)
The next log entry shows the actual changes by Paul Eggert.
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.
src/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.
src/lisp.h: Say "vectorlike header" rather than "vector header.
(struct vectorlike_header): Rename from struct vector_header.
(XVECTORLIKE_HEADER_SIZE): Renamed from XVECTOR_HEADER_SIZE.
All uses changed.
(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.
src/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".
src/buffer.h (struct buffer): Likewise.
src/font.h (struct font_spec, struct font_entity, struct font): Likewise.
src/frame.h (struct frame): Likewise.
src/process.h (struct Lisp_Process): Likewise.
src/termhooks.h (struct terminal): Likewise.
src/window.c (struct save_window_data, struct saved_window): Likewise.
src/window.h (struct window): Likewise.
src/alloc.c (allocate_buffer, Fmake_bool_vector, allocate_pseudovector):
Use XSETPVECTYPESIZE, not XSETPVECTYPE, to avoid aliasing problems.
src/buffer.c (init_buffer_once): Likewise.
src/lread.c (defsubr): Use XSETTYPED_PVECTYPE, since Lisp_Subr is a
special case.
src/process.c (Fformat_network_address): Use local var for size,
for brevity.
src/fns.c (vector): Remove; this old hack is no longer needed.
src/bytecode.c (exec_byte_code): Don't use XVECTOR before CHECK_VECTOR.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/process.c b/src/process.c index 9a33500dc4e..d4371fb8f32 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1277,25 +1277,26 @@ Returns nil if format of ADDRESS is invalid. */) | |||
| 1277 | if (VECTORP (address)) /* AF_INET or AF_INET6 */ | 1277 | if (VECTORP (address)) /* AF_INET or AF_INET6 */ |
| 1278 | { | 1278 | { |
| 1279 | register struct Lisp_Vector *p = XVECTOR (address); | 1279 | register struct Lisp_Vector *p = XVECTOR (address); |
| 1280 | EMACS_UINT size = p->header.size; | ||
| 1280 | Lisp_Object args[10]; | 1281 | Lisp_Object args[10]; |
| 1281 | int nargs, i; | 1282 | int nargs, i; |
| 1282 | 1283 | ||
| 1283 | if (p->size == 4 || (p->size == 5 && !NILP (omit_port))) | 1284 | if (size == 4 || (size == 5 && !NILP (omit_port))) |
| 1284 | { | 1285 | { |
| 1285 | args[0] = build_string ("%d.%d.%d.%d"); | 1286 | args[0] = build_string ("%d.%d.%d.%d"); |
| 1286 | nargs = 4; | 1287 | nargs = 4; |
| 1287 | } | 1288 | } |
| 1288 | else if (p->size == 5) | 1289 | else if (size == 5) |
| 1289 | { | 1290 | { |
| 1290 | args[0] = build_string ("%d.%d.%d.%d:%d"); | 1291 | args[0] = build_string ("%d.%d.%d.%d:%d"); |
| 1291 | nargs = 5; | 1292 | nargs = 5; |
| 1292 | } | 1293 | } |
| 1293 | else if (p->size == 8 || (p->size == 9 && !NILP (omit_port))) | 1294 | else if (size == 8 || (size == 9 && !NILP (omit_port))) |
| 1294 | { | 1295 | { |
| 1295 | args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); | 1296 | args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); |
| 1296 | nargs = 8; | 1297 | nargs = 8; |
| 1297 | } | 1298 | } |
| 1298 | else if (p->size == 9) | 1299 | else if (size == 9) |
| 1299 | { | 1300 | { |
| 1300 | args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d"); | 1301 | args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d"); |
| 1301 | nargs = 9; | 1302 | nargs = 9; |
| @@ -2477,13 +2478,13 @@ get_lisp_to_sockaddr_size (address, familyp) | |||
| 2477 | if (VECTORP (address)) | 2478 | if (VECTORP (address)) |
| 2478 | { | 2479 | { |
| 2479 | p = XVECTOR (address); | 2480 | p = XVECTOR (address); |
| 2480 | if (p->size == 5) | 2481 | if (p->header.size == 5) |
| 2481 | { | 2482 | { |
| 2482 | *familyp = AF_INET; | 2483 | *familyp = AF_INET; |
| 2483 | return sizeof (struct sockaddr_in); | 2484 | return sizeof (struct sockaddr_in); |
| 2484 | } | 2485 | } |
| 2485 | #ifdef AF_INET6 | 2486 | #ifdef AF_INET6 |
| 2486 | else if (p->size == 9) | 2487 | else if (p->header.size == 9) |
| 2487 | { | 2488 | { |
| 2488 | *familyp = AF_INET6; | 2489 | *familyp = AF_INET6; |
| 2489 | return sizeof (struct sockaddr_in6); | 2490 | return sizeof (struct sockaddr_in6); |
| @@ -2502,7 +2503,7 @@ get_lisp_to_sockaddr_size (address, familyp) | |||
| 2502 | struct sockaddr *sa; | 2503 | struct sockaddr *sa; |
| 2503 | *familyp = XINT (XCAR (address)); | 2504 | *familyp = XINT (XCAR (address)); |
| 2504 | p = XVECTOR (XCDR (address)); | 2505 | p = XVECTOR (XCDR (address)); |
| 2505 | return p->size + sizeof (sa->sa_family); | 2506 | return p->header.size + sizeof (sa->sa_family); |
| 2506 | } | 2507 | } |
| 2507 | return 0; | 2508 | return 0; |
| 2508 | } | 2509 | } |