From b9ff995e4c091ca99c8752bb996e155ce7147a00 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 10 Oct 2013 23:32:29 -0700 Subject: [PATCH] * lisp.h (eassume): New macro. Also, include , for 'assume'. * alloc.c (bool_vector_payload_bytes, Fmake_bool_vector) (vroundup, vector_nbytes): * data.c (bool_vector_spare_mask, bool_vector_binop_driver) (Fbool_vector_not, Fbool_vector_count_matches) (Fbool_vector_count_matches_at): Use eassume, not eassert. * casetab.c (set_identity, shuffle): * composite.c (composition_gstring_put_cache): * dispnew.c (update_frame_1): * ftfont.c (ftfont_shape_by_flt): * image.c (gif_load): * intervals.c (offset_intervals): * macfont.m (macfont_shape): Remove calls to 'assume' that are no longer needed, because --enable-gcc-warnings no longer generates bogus warnings when these calls are removed. --- src/ChangeLog | 21 +++++++++++++++++++++ src/alloc.c | 10 +++++----- src/casetab.c | 2 -- src/composite.c | 1 - src/data.c | 10 +++++----- src/dispnew.c | 1 - src/ftfont.c | 1 - src/image.c | 5 +---- src/intervals.c | 5 +---- src/lisp.h | 41 +++++++++++++++++++++++++++++++---------- src/macfont.m | 1 - 11 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index bfa9f2fae7d..df44bca7b1c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,24 @@ +2013-10-11 Paul Eggert + + * lisp.h (eassume): New macro. + Also, include , for 'assume'. + * alloc.c (bool_vector_payload_bytes, Fmake_bool_vector) + (vroundup, vector_nbytes): + * data.c (bool_vector_spare_mask, bool_vector_binop_driver) + (Fbool_vector_not, Fbool_vector_count_matches) + (Fbool_vector_count_matches_at): + Use eassume, not eassert. + * casetab.c (set_identity, shuffle): + * composite.c (composition_gstring_put_cache): + * dispnew.c (update_frame_1): + * ftfont.c (ftfont_shape_by_flt): + * image.c (gif_load): + * intervals.c (offset_intervals): + * macfont.m (macfont_shape): + Remove calls to 'assume' that are no longer needed, because + --enable-gcc-warnings no longer generates bogus warnings + when these calls are removed. + 2013-10-11 Dmitry Antipov * xdisp.c (deep_copy_glyph_row): Remove unused locals. diff --git a/src/alloc.c b/src/alloc.c index 17f1b19b3c0..0667353c1a8 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2027,7 +2027,7 @@ bool_vector_payload_bytes (ptrdiff_t nr_bits, ptrdiff_t exact_needed_bytes; ptrdiff_t needed_bytes; - eassert (nr_bits >= 0); + eassume (nr_bits >= 0); exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT; needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_BITS_WORD) / CHAR_BIT; @@ -2064,8 +2064,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) total_payload_bytes = bool_vector_payload_bytes (XFASTINT (length), &exact_payload_bytes); - eassert (exact_payload_bytes <= total_payload_bytes); - eassert (0 <= exact_payload_bytes); + eassume (exact_payload_bytes <= total_payload_bytes); + eassume (0 <= exact_payload_bytes); needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size) + total_payload_bytes), @@ -2622,7 +2622,7 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); /* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */ #define vroundup_ct(x) ROUNDUP ((size_t) (x), roundup_size) /* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime. */ -#define vroundup(x) (assume ((x) >= 0), vroundup_ct (x)) +#define vroundup(x) (eassume ((x) >= 0), vroundup_ct (x)) /* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ @@ -2820,7 +2820,7 @@ vector_nbytes (struct Lisp_Vector *v) ptrdiff_t payload_bytes = bool_vector_payload_bytes (bv->size, NULL); - eassert (payload_bytes >= 0); + eassume (payload_bytes >= 0); size = bool_header_size + ROUNDUP (payload_bytes, word_size); } else diff --git a/src/casetab.c b/src/casetab.c index 69cd784f4cc..e4907f5b628 100644 --- a/src/casetab.c +++ b/src/casetab.c @@ -205,7 +205,6 @@ set_identity (Lisp_Object table, Lisp_Object c, Lisp_Object elt) from = to = XINT (c); to++; - assume (to <= MAX_CHAR + 1); for (; from < to; from++) CHAR_TABLE_SET (table, from, make_number (from)); } @@ -232,7 +231,6 @@ shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt) from = to = XINT (c); to++; - assume (to <= MAX_CHAR + 1); for (; from < to; from++) { Lisp_Object tem = Faref (table, elt); diff --git a/src/composite.c b/src/composite.c index 4f125522e38..689ae95fa17 100644 --- a/src/composite.c +++ b/src/composite.c @@ -674,7 +674,6 @@ composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len) len = j; } - assume (len <= TYPE_MAXIMUM (ptrdiff_t) - 2); copy = Fmake_vector (make_number (len + 2), Qnil); LGSTRING_SET_HEADER (copy, Fcopy_sequence (header)); for (i = 0; i < len; i++) diff --git a/src/data.c b/src/data.c index 8045cd138ea..b4257243fb3 100644 --- a/src/data.c +++ b/src/data.c @@ -2969,7 +2969,7 @@ lowercase l) for small endian machines. */) static bits_word bool_vector_spare_mask (ptrdiff_t nr_bits) { - eassert (nr_bits > 0); + eassume (nr_bits > 0); return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; } @@ -3019,7 +3019,7 @@ bool_vector_binop_driver (Lisp_Object op1, nr_bits = min (nr_bits, XBOOL_VECTOR (dest)->size); } - eassert (nr_bits >= 0); + eassume (nr_bits >= 0); nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; adata = (bits_word *) XBOOL_VECTOR (dest)->data; @@ -3185,7 +3185,7 @@ Return the destination vector. */) bdata = (bits_word *) XBOOL_VECTOR (b)->data; adata = (bits_word *) XBOOL_VECTOR (a)->data; - eassert (nr_bits >= 0); + eassume (nr_bits >= 0); for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++) bdata[i] = ~adata[i]; @@ -3220,7 +3220,7 @@ A must be a bool vector. B is a generalized bool. */) match = NILP (b) ? -1 : 0; adata = (bits_word *) XBOOL_VECTOR (a)->data; - eassert (nr_bits >= 0); + eassume (nr_bits >= 0); for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; ++i) count += popcount_bits_word (adata[i] ^ match); @@ -3262,7 +3262,7 @@ index into the vector. */) adata = (bits_word *) XBOOL_VECTOR (a)->data; - assume (nr_bits >= 0); + eassume (nr_bits >= 0); nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; pos = XFASTINT (i) / BITS_PER_BITS_WORD; diff --git a/src/dispnew.c b/src/dispnew.c index f5adb359f22..e3a1c1b49cb 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -4480,7 +4480,6 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) } } - assume (0 <= FRAME_LINES (f)); pause_p = 0 < i && i < FRAME_LINES (f) - 1; /* Now just clean up termcap drivers and set cursor, etc. */ diff --git a/src/ftfont.c b/src/ftfont.c index 4e58d83fd64..eeee56891ec 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -2425,7 +2425,6 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, } len = i; - assume (len <= STRING_BYTES_BOUND); if (with_variation_selector) { diff --git a/src/image.c b/src/image.c index 86780c62a0b..ca2ef67c0b9 100644 --- a/src/image.c +++ b/src/image.c @@ -7571,10 +7571,7 @@ gif_load (struct frame *f, struct image *img) y++, row += interlace_increment[pass]) { while (subimg_height <= row) - { - assume (pass < 3); - row = interlace_start[++pass]; - } + row = interlace_start[++pass]; for (x = 0; x < subimg_width; x++) { diff --git a/src/intervals.c b/src/intervals.c index a9c4f5aed0b..5aa68a359d6 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -1404,10 +1404,7 @@ offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length) adjust_intervals_for_insertion (buffer_intervals (buffer), start, length); else - { - assume (- TYPE_MAXIMUM (ptrdiff_t) <= length); - adjust_intervals_for_deletion (buffer, start, -length); - } + adjust_intervals_for_deletion (buffer, start, -length); } /* Merge interval I with its lexicographic successor. The resulting diff --git a/src/lisp.h b/src/lisp.h index 6638cc66e9f..e4a2caa1083 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include INLINE_HEADER_BEGIN @@ -113,28 +114,48 @@ typedef EMACS_UINT uprintmax_t; /* Extra internal type checking? */ -/* Define an Emacs version of 'assert (COND)'. COND should be free of - side effects; it may be evaluated zero or more times. */ +/* Define Emacs versions of 's 'assert (COND)' and 's + 'assume (COND)'. COND should be free of side effects, as it may or + may not be evaluated. + + 'eassert (COND)' checks COND at runtime if ENABLE_CHECKING is + defined and suppress_checking is false, and does nothing otherwise. + Emacs dies if COND is checked and is false. The suppress_checking + variable is initialized to 0 in alloc.c. Set it to 1 using a + debugger to temporarily disable aborting on detected internal + inconsistencies or error conditions. + + In some cases, a good compiler may be able to optimize away the + eassert macro even if ENABLE_CHECKING is true, e.g., if XSTRING (x) + uses eassert to test STRINGP (x), but a particular use of XSTRING + is invoked only after testing that STRINGP (x) is true, making the + test redundant. + + eassume is like eassert except that it also causes the compiler to + assume that COND is true afterwards, regardless of whether runtime + checking is enabled. This can improve performance in some cases, + though it can degrade performance in others. It's often suboptimal + for COND to call external functions or access volatile storage. */ + #ifndef ENABLE_CHECKING # define eassert(cond) ((void) (0 && (cond))) /* Check that COND compiles. */ +# define eassume(cond) assume (cond) #else /* ENABLE_CHECKING */ extern _Noreturn void die (const char *, const char *, int); -/* The suppress_checking variable is initialized to 0 in alloc.c. Set - it to 1 using a debugger to temporarily disable aborting on - detected internal inconsistencies or error conditions. - - In some cases, a good compiler may be able to optimize away the - eassert macro altogether, e.g., if XSTRING (x) uses eassert to test - STRINGP (x), but a particular use of XSTRING is invoked only after - testing that STRINGP (x) is true, making the test redundant. */ extern bool suppress_checking EXTERNALLY_VISIBLE; # define eassert(cond) \ (suppress_checking || (cond) \ ? (void) 0 \ : die (# cond, __FILE__, __LINE__)) +# define eassume(cond) \ + (suppress_checking \ + ? assume (cond) \ + : (cond) \ + ? (void) 0 \ + : die (# cond, __FILE__, __LINE__)) #endif /* ENABLE_CHECKING */ diff --git a/src/macfont.m b/src/macfont.m index 206a810c239..b3bf96d8c4e 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -2817,7 +2817,6 @@ macfont_shape (Lisp_Object lgstring) } len = i; - assume (len <= TYPE_MAXIMUM (EMACS_INT) - 2); if (INT_MAX / 2 < len) memory_full (SIZE_MAX); -- 2.11.4.GIT