This function returns @var{buffer}'s modification-count. This is a
counter that increments every time the buffer is modified. If
@var{buffer} is @code{nil} (or omitted), the current buffer is used.
-The counter can wrap around occasionally.
@end defun
@defun buffer-chars-modified-tick &optional buffer
/* If SAVE_MODIFF == auto_save_modified == MODIFF,
we can either decrease SAVE_MODIFF and auto_save_modified
or increase MODIFF. */
- : MODIFF++);
+ : modiff_incr (&MODIFF));
return flag;
}
0, 1, 0,
doc: /* Return BUFFER's tick counter, incremented for each change in text.
Each buffer has a tick counter which is incremented each time the
-text in that buffer is changed. It wraps around occasionally.
-No argument or nil as argument means use current buffer as BUFFER. */)
- (register Lisp_Object buffer)
+text in that buffer is changed. No argument or nil as argument means
+use current buffer as BUFFER. */)
+ (Lisp_Object buffer)
{
- return make_fixnum (BUF_MODIFF (decode_buffer (buffer)));
+ return modiff_to_integer (BUF_MODIFF (decode_buffer (buffer)));
}
DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
you can tell whether a character change occurred in that buffer in
between these calls. No argument or nil as argument means use current
buffer as BUFFER. */)
- (register Lisp_Object buffer)
+ (Lisp_Object buffer)
{
- return make_fixnum (BUF_CHARS_MODIFF (decode_buffer (buffer)));
+ return modiff_to_integer (BUF_CHARS_MODIFF (decode_buffer (buffer)));
}
\f
DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
bset_point_before_scroll (current_buffer, Qnil);
bset_point_before_scroll (other_buffer, Qnil);
- current_buffer->text->modiff++; other_buffer->text->modiff++;
- current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++;
- current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++;
+ modiff_incr (¤t_buffer->text->modiff);
+ modiff_incr (&other_buffer->text->modiff);
+ modiff_incr (¤t_buffer->text->chars_modiff);
+ modiff_incr (&other_buffer->text->chars_modiff);
+ modiff_incr (¤t_buffer->text->overlay_modiff);
+ modiff_incr (&other_buffer->text->overlay_modiff);
current_buffer->text->beg_unchanged = current_buffer->text->gpt;
current_buffer->text->end_unchanged = current_buffer->text->gpt;
other_buffer->text->beg_unchanged = other_buffer->text->gpt;
bset_redisplay (buf);
- ++BUF_OVERLAY_MODIFF (buf);
+ modiff_incr (&BUF_OVERLAY_MODIFF (buf));
}
/* Remove OVERLAY from LIST. */
ptrdiff_t gpt_byte; /* Byte pos of gap in buffer. */
ptrdiff_t z_byte; /* Byte pos of end of buffer. */
ptrdiff_t gap_size; /* Size of buffer's gap. */
- EMACS_INT modiff; /* This counts buffer-modification events
+ modiff_count modiff; /* This counts buffer-modification events
for this buffer. It is incremented for
each such event, and never otherwise
changed. */
- EMACS_INT chars_modiff; /* This is modified with character change
+ modiff_count chars_modiff; /* This is modified with character change
events for this buffer. It is set to
modiff for each such event, and never
otherwise changed. */
- EMACS_INT save_modiff; /* Previous value of modiff, as of last
+ modiff_count save_modiff; /* Previous value of modiff, as of last
time buffer visited or saved a file. */
- EMACS_INT overlay_modiff; /* Counts modifications to overlays. */
+ modiff_count overlay_modiff; /* Counts modifications to overlays. */
- EMACS_INT compact; /* Set to modiff each time when compact_buffer
+ modiff_count compact; /* Set to modiff each time when compact_buffer
is called for this buffer. */
/* Minimum value of GPT - BEG since last redisplay that finished. */
/* MODIFF as of last redisplay that finished; if it matches MODIFF,
beg_unchanged and end_unchanged contain no useful information. */
- EMACS_INT unchanged_modified;
+ modiff_count unchanged_modified;
/* BUF_OVERLAY_MODIFF of current buffer, as of last redisplay that
finished; if it matches BUF_OVERLAY_MODIFF, beg_unchanged and
end_unchanged contain no useful information. */
- EMACS_INT overlay_unchanged_modified;
+ modiff_count overlay_unchanged_modified;
/* Properties of this buffer's text. */
INTERVAL intervals;
off_t modtime_size;
/* The value of text->modiff at the last auto-save. */
- EMACS_INT auto_save_modified;
+ modiff_count auto_save_modified;
/* The value of text->modiff at the last display error.
Redisplay of this buffer is inhibited until it changes again. */
- EMACS_INT display_error_modiff;
+ modiff_count display_error_modiff;
/* The time at which we detected a failure to auto-save,
Or 0 if we didn't have a failure. */
: UNIBYTE_TO_CHAR (XFIXNAT (Fprevious_char ())))
== Sword))
{
- EMACS_INT modiff = MODIFF;
+ modiff_count modiff = MODIFF;
Lisp_Object sym;
sym = call0 (Qexpand_abbrev);
if (! NILP (noundo))
{
- if (MODIFF - 1 == SAVE_MODIFF)
- SAVE_MODIFF++;
- if (MODIFF - 1 == BUF_AUTOSAVE_MODIFF (current_buffer))
- BUF_AUTOSAVE_MODIFF (current_buffer)++;
+ modiff_count m = MODIFF;
+ if (SAVE_MODIFF == m - 1)
+ SAVE_MODIFF = m;
+ if (BUF_AUTOSAVE_MODIFF (current_buffer) == m - 1)
+ BUF_AUTOSAVE_MODIFF (current_buffer) = m;
}
/* The before-change-function may have moved the gap
ptrdiff_t opoint = PT;
ptrdiff_t opoint_byte = PT_BYTE;
ptrdiff_t oinserted = ZV - BEGV;
- EMACS_INT ochars_modiff = CHARS_MODIFF;
+ modiff_count ochars_modiff = CHARS_MODIFF;
TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
insval = call3 (Qformat_decode,
ptrdiff_t opoint = PT;
ptrdiff_t opoint_byte = PT_BYTE;
ptrdiff_t oinserted = ZV - BEGV;
- EMACS_INT ochars_modiff = CHARS_MODIFF;
+ modiff_count ochars_modiff = CHARS_MODIFF;
TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
insval = call1 (XCAR (p), make_fixnum (oinserted));
/* Value of MODIFF when current_column was called. */
-static EMACS_INT last_known_column_modified;
+static modiff_count last_known_column_modified;
static ptrdiff_t current_column_1 (void);
static ptrdiff_t position_indentation (ptrdiff_t);
the insertion. This, together with recording the insertion,
will add up to the right stuff in the undo list. */
record_insert (PT, nchars);
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
memcpy (GPT_ADDR, string, nbytes);
#endif
record_insert (PT, nchars);
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
GAP_SIZE -= outgoing_nbytes;
of this dance. */
invalidate_buffer_caches (current_buffer, GPT, GPT);
record_insert (GPT, nchars);
- MODIFF++;
+ modiff_incr (&MODIFF);
GAP_SIZE -= nbytes;
if (! text_at_gap_tail)
#endif
record_insert (PT, nchars);
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
GAP_SIZE -= outgoing_nbytes;
if (len == 0)
evaporate_overlays (from);
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
}
check_markers ();
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
if (adjust_match_data)
check_markers ();
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
}
\f
at the end of the text before the gap. */
adjust_markers_for_delete (from, from_byte, to, to_byte);
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
/* Relocate point as if it were a marker. */
BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
- MODIFF++;
+ modiff_incr (&MODIFF);
CHARS_MODIFF = MODIFF;
bset_point_before_scroll (current_buffer, Qnil);
Lisp_Object
command_loop_1 (void)
{
- EMACS_INT prev_modiff = 0;
+ modiff_count prev_modiff = 0;
struct buffer *prev_buffer = NULL;
bool already_adjusted = 0;
}
}
+/* A modification count. These are wide enough, and incremented
+ rarely enough, so that they should never overflow a 60-bit counter
+ in practice, and the code below assumes this so a compiler can
+ generate better code if EMACS_INT is 64 bits. */
+typedef intmax_t modiff_count;
+
+INLINE modiff_count
+modiff_incr (modiff_count *a)
+{
+ modiff_count a0 = *a;
+ bool modiff_overflow = INT_ADD_WRAPV (a0, 1, a);
+ eassert (!modiff_overflow && *a >> 30 >> 30 == 0);
+ return a0;
+}
+
+INLINE Lisp_Object
+modiff_to_integer (modiff_count a)
+{
+ eassume (0 <= a && a >> 30 >> 30 == 0);
+ return make_int (a);
+}
+
/* Defined in data.c. */
extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object);
extern void notify_variable_watchers (Lisp_Object, Lisp_Object,
static ptrdiff_t cached_charpos;
static ptrdiff_t cached_bytepos;
static struct buffer *cached_buffer;
-static EMACS_INT cached_modiff;
+static modiff_count cached_modiff;
/* Juanma Barranquero <lekktu@gmail.com> reported ~3x increased
bootstrap time when byte_char_debug_check is enabled; so this
static dump_off
dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
{
-#if CHECK_STRUCTS && !defined (HASH_buffer_E8695CAE09)
+#if CHECK_STRUCTS && !defined HASH_buffer_AE2C8CE357
# error "buffer changed. See CHECK_STRUCTS comment."
#endif
struct buffer munged_buffer = *in_buffer;
static ptrdiff_t find_start_value_byte;
static struct buffer *find_start_buffer;
static ptrdiff_t find_start_begv;
-static EMACS_INT find_start_modiff;
+static modiff_count find_start_modiff;
static Lisp_Object skip_chars (bool, Lisp_Object, Lisp_Object, bool);
if (syntax_propertize__done <= charpos
&& syntax_propertize__done < zv)
{
- EMACS_INT modiffs = CHARS_MODIFF;
+ modiff_count modiffs = CHARS_MODIFF;
safe_call1 (Qinternal__syntax_propertize,
make_fixnum (min (zv, 1 + charpos)));
if (modiffs != CHARS_MODIFF)
if (!NILP (Vcomment_use_syntax_ppss))
{
- EMACS_INT modiffs = CHARS_MODIFF;
+ modiff_count modiffs = CHARS_MODIFF;
Lisp_Object ppss = call1 (Qsyntax_ppss, make_fixnum (pos));
if (modiffs != CHARS_MODIFF)
error ("syntax-ppss modified the buffer!");
BUF_COMPUTE_UNCHANGED (buf, b - 1, e);
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
- MODIFF++;
+ modiff_incr (&MODIFF);
bset_point_before_scroll (current_buffer, Qnil);
/* Displayed buffer's text modification events counter as of last time
display completed. */
- EMACS_INT last_modified;
+ modiff_count last_modified;
/* Displayed buffer's overlays modification events counter as of last
complete update. */
- EMACS_INT last_overlay_modified;
+ modiff_count last_overlay_modified;
/* Value of point at that time. Since this is a position in a buffer,
it should be positive. */