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/buffer.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/buffer.c')
| -rw-r--r-- | src/buffer.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/src/buffer.c b/src/buffer.c index 076495cfc64..70d7d00edfe 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -53,7 +53,7 @@ extern int errno; | |||
| 53 | struct buffer *current_buffer; /* the current buffer */ | 53 | struct buffer *current_buffer; /* the current buffer */ |
| 54 | 54 | ||
| 55 | /* First buffer in chain of all buffers (in reverse order of creation). | 55 | /* First buffer in chain of all buffers (in reverse order of creation). |
| 56 | Threaded through ->next. */ | 56 | Threaded through ->header.next.buffer. */ |
| 57 | 57 | ||
| 58 | struct buffer *all_buffers; | 58 | struct buffer *all_buffers; |
| 59 | 59 | ||
| @@ -400,7 +400,7 @@ even if it is dead. The return value is never nil. */) | |||
| 400 | b->prevent_redisplay_optimizations_p = 1; | 400 | b->prevent_redisplay_optimizations_p = 1; |
| 401 | 401 | ||
| 402 | /* Put this on the chain of all buffers including killed ones. */ | 402 | /* Put this on the chain of all buffers including killed ones. */ |
| 403 | b->next = all_buffers; | 403 | b->header.next.buffer = all_buffers; |
| 404 | all_buffers = b; | 404 | all_buffers = b; |
| 405 | 405 | ||
| 406 | /* An ordinary buffer normally doesn't need markers | 406 | /* An ordinary buffer normally doesn't need markers |
| @@ -633,7 +633,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 633 | b->width_table = Qnil; | 633 | b->width_table = Qnil; |
| 634 | 634 | ||
| 635 | /* Put this on the chain of all buffers including killed ones. */ | 635 | /* Put this on the chain of all buffers including killed ones. */ |
| 636 | b->next = all_buffers; | 636 | b->header.next.buffer = all_buffers; |
| 637 | all_buffers = b; | 637 | all_buffers = b; |
| 638 | 638 | ||
| 639 | name = Fcopy_sequence (name); | 639 | name = Fcopy_sequence (name); |
| @@ -1544,7 +1544,7 @@ with SIGHUP. */) | |||
| 1544 | 1544 | ||
| 1545 | GCPRO1 (buffer); | 1545 | GCPRO1 (buffer); |
| 1546 | 1546 | ||
| 1547 | for (other = all_buffers; other; other = other->next) | 1547 | for (other = all_buffers; other; other = other->header.next.buffer) |
| 1548 | /* all_buffers contains dead buffers too; | 1548 | /* all_buffers contains dead buffers too; |
| 1549 | don't re-kill them. */ | 1549 | don't re-kill them. */ |
| 1550 | if (other->base_buffer == b && !NILP (other->name)) | 1550 | if (other->base_buffer == b && !NILP (other->name)) |
| @@ -2214,7 +2214,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | |||
| 2214 | 2214 | ||
| 2215 | { /* This is probably harder to make work. */ | 2215 | { /* This is probably harder to make work. */ |
| 2216 | struct buffer *other; | 2216 | struct buffer *other; |
| 2217 | for (other = all_buffers; other; other = other->next) | 2217 | for (other = all_buffers; other; other = other->header.next.buffer) |
| 2218 | if (other->base_buffer == other_buffer | 2218 | if (other->base_buffer == other_buffer |
| 2219 | || other->base_buffer == current_buffer) | 2219 | || other->base_buffer == current_buffer) |
| 2220 | error ("One of the buffers to swap has indirect buffers"); | 2220 | error ("One of the buffers to swap has indirect buffers"); |
| @@ -2585,7 +2585,7 @@ current buffer is cleared. */) | |||
| 2585 | 2585 | ||
| 2586 | /* Copy this buffer's new multibyte status | 2586 | /* Copy this buffer's new multibyte status |
| 2587 | into all of its indirect buffers. */ | 2587 | into all of its indirect buffers. */ |
| 2588 | for (other = all_buffers; other; other = other->next) | 2588 | for (other = all_buffers; other; other = other->header.next.buffer) |
| 2589 | if (other->base_buffer == current_buffer && !NILP (other->name)) | 2589 | if (other->base_buffer == current_buffer && !NILP (other->name)) |
| 2590 | { | 2590 | { |
| 2591 | other->enable_multibyte_characters | 2591 | other->enable_multibyte_characters |
| @@ -4346,7 +4346,7 @@ static void | |||
| 4346 | add_overlay_mod_hooklist (functionlist, overlay) | 4346 | add_overlay_mod_hooklist (functionlist, overlay) |
| 4347 | Lisp_Object functionlist, overlay; | 4347 | Lisp_Object functionlist, overlay; |
| 4348 | { | 4348 | { |
| 4349 | int oldsize = XVECTOR (last_overlay_modification_hooks)->size; | 4349 | int oldsize = XVECTOR_SIZE (last_overlay_modification_hooks); |
| 4350 | 4350 | ||
| 4351 | if (last_overlay_modification_hooks_used == oldsize) | 4351 | if (last_overlay_modification_hooks_used == oldsize) |
| 4352 | last_overlay_modification_hooks = larger_vector | 4352 | last_overlay_modification_hooks = larger_vector |
| @@ -5150,9 +5150,9 @@ init_buffer_once () | |||
| 5150 | buffer_local_symbols.text = &buffer_local_symbols.own_text; | 5150 | buffer_local_symbols.text = &buffer_local_symbols.own_text; |
| 5151 | BUF_INTERVALS (&buffer_defaults) = 0; | 5151 | BUF_INTERVALS (&buffer_defaults) = 0; |
| 5152 | BUF_INTERVALS (&buffer_local_symbols) = 0; | 5152 | BUF_INTERVALS (&buffer_local_symbols) = 0; |
| 5153 | XSETPVECTYPE (&buffer_defaults, PVEC_BUFFER); | 5153 | XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, 0); |
| 5154 | XSETBUFFER (Vbuffer_defaults, &buffer_defaults); | 5154 | XSETBUFFER (Vbuffer_defaults, &buffer_defaults); |
| 5155 | XSETPVECTYPE (&buffer_local_symbols, PVEC_BUFFER); | 5155 | XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, 0); |
| 5156 | XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols); | 5156 | XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols); |
| 5157 | 5157 | ||
| 5158 | /* Set up the default values of various buffer slots. */ | 5158 | /* Set up the default values of various buffer slots. */ |