APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1541015012 0
# Wed Oct 31 19:43:32 2018 +0000
# Node ID 3aad17c73ee317fa5073c61999dc0143f8c351ec
# Parent c3ddb84e1c4a0e8a2696ad0b6528172e320c45e2
Reduce calls to marker_position() further, redisplay
2018-10-31 Aidan Kehoe <kehoea(a)parhasard.net>
* redisplay-output.c (redisplay_move_cursor):
* redisplay-output.c (redisplay_update_line):
* redisplay-output.c (redisplay_output_window):
* redisplay.c:
* redisplay.c (generate_display_line):
* redisplay.c (regenerate_window_extents_only_changed):
* redisplay.c (redisplay_window):
Reduce the use of marker_position() in all these functions, using
byte marker positions instead, making redisplay consistently a
little faster and reducing unpredictable slowdowns on Mule.
* redisplay.c (decode_mode_spec):
Move the functionality window_line_number() into this function, no
need for a static buffer.
diff -r c3ddb84e1c4a -r 3aad17c73ee3 src/ChangeLog
--- a/src/ChangeLog Mon Oct 29 11:15:34 2018 +0000
+++ b/src/ChangeLog Wed Oct 31 19:43:32 2018 +0000
@@ -1,3 +1,20 @@
+2018-10-31 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * redisplay-output.c (redisplay_move_cursor):
+ * redisplay-output.c (redisplay_update_line):
+ * redisplay-output.c (redisplay_output_window):
+ * redisplay.c:
+ * redisplay.c (generate_display_line):
+ * redisplay.c (regenerate_window_extents_only_changed):
+ * redisplay.c (redisplay_window):
+ Reduce the use of marker_position() in all these functions, using
+ byte marker positions instead, making redisplay consistently a
+ little faster and reducing unpredictable slowdowns on Mule.
+
+ * redisplay.c (decode_mode_spec):
+ Move the functionality window_line_number() into this function, no
+ need for a static buffer.
+
2018-10-29 Aidan Kehoe <kehoea(a)parhasard.net>
* indent.c:
diff -r c3ddb84e1c4a -r 3aad17c73ee3 src/redisplay-output.c
--- a/src/redisplay-output.c Mon Oct 29 11:15:34 2018 +0000
+++ b/src/redisplay-output.c Wed Oct 31 19:43:32 2018 +0000
@@ -1028,8 +1028,8 @@
{
w->last_point_x[CURRENT_DISP] = 0;
w->last_point_y[CURRENT_DISP] = y;
- Fset_marker (w->last_point[CURRENT_DISP], Qzero, w->buffer);
-
+ set_byte_marker_position (w->last_point[CURRENT_DISP],
+ BYTE_BUF_BEG (w->buffer), w->buffer);
rb = Dynarr_begin (db->runes);
rb->cursor_type = CURSOR_ON;
dl->cursor_elt = 0;
@@ -2315,10 +2315,12 @@
w->last_modified[CURRENT_DISP] = w->last_modified[DESIRED_DISP];
w->last_facechange[CURRENT_DISP] = w->last_facechange[DESIRED_DISP];
- Fset_marker (w->last_point[CURRENT_DISP],
- Fmarker_position (w->last_point[DESIRED_DISP]), w->buffer);
- Fset_marker (w->last_start[CURRENT_DISP],
- Fmarker_position (w->last_start[DESIRED_DISP]), w->buffer);
+ set_byte_marker_position (w->last_point[CURRENT_DISP],
+ byte_marker_position (w->last_point[DESIRED_DISP]),
+ w->buffer);
+ set_byte_marker_position (w->last_start[CURRENT_DISP],
+ byte_marker_position (w->last_start[DESIRED_DISP]),
+ w->buffer);
/* We don't bother updating the vertical scrollbars here. This
gives us a performance increase while having minimal loss of
@@ -2489,18 +2491,20 @@
}
w->window_end_pos[CURRENT_DISP] = w->window_end_pos[DESIRED_DISP];
- Fset_marker (w->start[CURRENT_DISP],
- make_fixnum (marker_position (w->start[DESIRED_DISP])),
- w->buffer);
- Fset_marker (w->pointm[CURRENT_DISP],
- make_fixnum (marker_position (w->pointm[DESIRED_DISP])),
- w->buffer);
+ set_byte_marker_position (w->start[CURRENT_DISP],
+ byte_marker_position (w->start[DESIRED_DISP]),
+ w->buffer);
+ set_byte_marker_position (w->pointm[CURRENT_DISP],
+ byte_marker_position (w->pointm[DESIRED_DISP]),
+ w->buffer);
w->last_modified[CURRENT_DISP] = w->last_modified[DESIRED_DISP];
w->last_facechange[CURRENT_DISP] = w->last_facechange[DESIRED_DISP];
- Fset_marker (w->last_start[CURRENT_DISP],
- Fmarker_position (w->last_start[DESIRED_DISP]), w->buffer);
- Fset_marker (w->last_point[CURRENT_DISP],
- Fmarker_position (w->last_point[DESIRED_DISP]), w->buffer);
+ set_byte_marker_position (w->last_start[CURRENT_DISP],
+ byte_marker_position (w->last_start[DESIRED_DISP]),
+ w->buffer);
+ set_byte_marker_position (w->last_point[CURRENT_DISP],
+ byte_marker_position (w->last_point[DESIRED_DISP]),
+ w->buffer);
w->last_point_x[CURRENT_DISP] = w->last_point_x[DESIRED_DISP];
w->last_point_y[CURRENT_DISP] = w->last_point_y[DESIRED_DISP];
w->shadow_thickness_changed = 0;
diff -r c3ddb84e1c4a -r 3aad17c73ee3 src/redisplay.c
--- a/src/redisplay.c Mon Oct 29 11:15:34 2018 +0000
+++ b/src/redisplay.c Wed Oct 31 19:43:32 2018 +0000
@@ -920,6 +920,7 @@
Charbpos ret_charpos;
int overlay_width;
struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
+ Bytebpos byte_start_pos;
/* If our caller hasn't already set the boundaries, then do so now. */
if (!bounds)
@@ -941,13 +942,12 @@
/* We aren't generating a modeline at the moment. */
dl->modeline = 0;
-
+ byte_start_pos = charbpos_to_bytebpos (b, start_pos);
/* Create a display block for the text region of the line. */
{
/* #### urk urk urk!!! Chuck fix this shit! */
Bytebpos hacked_up_bytebpos =
- create_text_block (w, dl, charbpos_to_bytebpos (b, start_pos),
- prop, type);
+ create_text_block (w, dl, byte_start_pos, prop, type);
if (hacked_up_bytebpos > BYTE_BUF_ZV (b))
ret_charpos = BUF_ZV (b) + 1;
else
@@ -959,7 +959,7 @@
if (MARKERP (Voverlay_arrow_position)
&& EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
- && start_pos == marker_position (Voverlay_arrow_position)
+ && byte_start_pos == byte_marker_position (Voverlay_arrow_position)
&& (STRINGP (Voverlay_arrow_string)
|| GLYPHP (Voverlay_arrow_string)))
{
@@ -5786,6 +5786,7 @@
/* Don't define this in the loop where it is used because we
definitely want its value to survive between passes. */
prop_block_dynarr *prop = NULL;
+ Bytebpos byte_pointm;
/* If we don't have any buffer change recorded but the modiff flag has
been incremented, then fail. I'm not sure of the exact circumstances
@@ -5795,10 +5796,12 @@
|| XFIXNUM (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
return 0;
+ byte_pointm = charbpos_to_bytebpos (b, pointm);
+
/* If the cursor is moved we attempt to update it. If we succeed we
go ahead and proceed with the optimization attempt. */
if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
- || pointm != marker_position (w->last_point[CURRENT_DISP]))
+ || byte_pointm != byte_marker_position (w->last_point[CURRENT_DISP]))
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
@@ -5860,7 +5863,7 @@
if (line > dla_end)
{
if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
- && pointm == marker_position (w->last_point[CURRENT_DISP]))
+ && byte_pointm == byte_marker_position (w->last_point[CURRENT_DISP]))
return 1;
else
return 0;
@@ -5876,7 +5879,8 @@
w->last_modified[DESIRED_DISP] = make_fixnum (BUF_MODIFF (b));
w->last_facechange[DESIRED_DISP] = make_fixnum (BUF_FACECHANGE (b));
Fset_marker (w->last_start[DESIRED_DISP], make_fixnum (startp), w->buffer);
- Fset_marker (w->last_point[DESIRED_DISP], make_fixnum (pointm), w->buffer);
+ set_byte_marker_position (w->last_point[DESIRED_DISP],
+ byte_pointm, w->buffer);
first_line = last_line = line;
while (line <= dla_end)
@@ -6284,8 +6288,8 @@
int echo_active = 0;
int startp = 1;
int pointm;
- int old_startp = 1;
- int old_pointm = 1;
+ Bytebpos old_startp = 1;
+ Bytebpos old_pointm = 1;
int selected_in_its_frame;
int selected_globally;
int skip_output = 0;
@@ -6338,27 +6342,35 @@
if (echo_active)
{
old_pointm = selected_globally
- ? BUF_PT (b)
- : marker_position (w->pointm[CURRENT_DISP]);
- pointm = 1;
+ ? BYTE_BUF_PT (b)
+ : byte_marker_position (w->pointm[CURRENT_DISP]);
+ pointm = BUF_BEG (the_buffer);
+ set_byte_marker_position (w->pointm[DESIRED_DISP], BYTE_BUF_BEG (b),
+ the_buffer);
}
else
{
if (selected_globally)
{
pointm = BUF_PT (b);
+ set_byte_marker_position (w->pointm[DESIRED_DISP], BYTE_BUF_PT (b),
+ the_buffer);
+
}
else
{
- pointm = marker_position (w->pointm[CURRENT_DISP]);
-
- if (pointm < BUF_BEGV (b))
- pointm = BUF_BEGV (b);
- else if (pointm > BUF_ZV (b))
- pointm = BUF_ZV (b);
- }
- }
- Fset_marker (w->pointm[DESIRED_DISP], make_fixnum (pointm), the_buffer);
+ Bytebpos byte_pointm
+ = byte_marker_position (w->pointm[CURRENT_DISP]);
+
+ if (byte_pointm < BYTE_BUF_BEGV (b))
+ byte_pointm = BYTE_BUF_BEGV (b);
+ else if (byte_pointm > BYTE_BUF_ZV (b))
+ byte_pointm = BYTE_BUF_ZV (b);
+ set_byte_marker_position (w->pointm[DESIRED_DISP], byte_pointm,
+ the_buffer);
+ pointm = bytebpos_to_charbpos (b, byte_pointm);
+ }
+ }
/* Added 2-1-10 -- we should never have empty face or glyph cachels
because we initialized them at startup and the only way to reduce
@@ -6403,18 +6415,33 @@
if (echo_active)
{
- old_startp = marker_position (w->start[CURRENT_DISP]);
- startp = 1;
+ old_startp = byte_marker_position (w->start[CURRENT_DISP]);
+
+ startp = BUF_BEG (b);
+ set_byte_marker_position (w->start[DESIRED_DISP], BYTE_BUF_BEG (b),
+ the_buffer);
}
else
{
- startp = marker_position (w->start[CURRENT_DISP]);
- if (startp < BUF_BEGV (b))
- startp = BUF_BEGV (b);
- else if (startp > BUF_ZV (b))
- startp = BUF_ZV (b);
- }
- Fset_marker (w->start[DESIRED_DISP], make_fixnum (startp), the_buffer);
+ Bytebpos byte_startp = byte_marker_position (w->start[CURRENT_DISP]);
+ if (byte_startp < BYTE_BUF_BEGV (b))
+ {
+ byte_startp = BYTE_BUF_BEGV (b);
+ startp = BUF_BEGV (b);
+ }
+ else if (byte_startp > BYTE_BUF_ZV (b))
+ {
+ byte_startp = BYTE_BUF_ZV (b);
+ startp = BUF_ZV (b);
+ }
+ else
+ {
+ startp = bytebpos_to_charbpos (b, byte_startp);
+ }
+
+ set_byte_marker_position (w->start[DESIRED_DISP], byte_startp,
+ the_buffer);
+ }
truncation_changed = (find_window_mirror (w)->truncate_win !=
(unsigned int) window_truncation_on (w));
@@ -6464,7 +6491,6 @@
{
/* Check if the cursor has actually moved. */
if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
- && pointm == marker_position (w->last_point[CURRENT_DISP])
&& selected_globally
&& !w->windows_changed
&& !f->clip_changed
@@ -6474,7 +6500,8 @@
&& !f->subwindows_changed
/* && !f->subwindows_state_changed*/
&& !f->point_changed
- && !f->windows_structure_changed)
+ && !f->windows_structure_changed
+ && pointm == marker_position (w->last_point[CURRENT_DISP]))
{
/* If not, we're done. */
if (f->modeline_changed)
@@ -6616,8 +6643,10 @@
if (echo_active)
{
w->buffer = old_buffer;
- Fset_marker (w->pointm[DESIRED_DISP], make_fixnum (old_pointm), old_buffer);
- Fset_marker (w->start[DESIRED_DISP], make_fixnum (old_startp), old_buffer);
+ set_byte_marker_position (w->pointm[DESIRED_DISP], old_pointm,
+ old_buffer);
+ set_byte_marker_position (w->start[DESIRED_DISP], old_startp,
+ old_buffer);
}
/* These also have to be set before calling redisplay_output_window
@@ -7294,41 +7323,6 @@
dont_trust_this_damn_sucker, 0);
}
-/* Efficiently determine the window line number, and return a pointer
- to its printed representation. Do this regardless of whether
- line-number-mode is on. The first line in the buffer is counted as
- 1. If narrowing is in effect, the lines are counted from the
- beginning of the visible portion of the buffer. */
-static Ibyte *
-window_line_number (struct window *w, int type)
-{
- struct device *d = XDEVICE (XFRAME (w->frame)->device);
- struct buffer *b = XBUFFER (w->buffer);
- /* Be careful in the order of these tests. The first clause will
- fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
- This can occur when the frame title is computed really early */
- Bytebpos pos =
- ((EQ (DEVICE_SELECTED_FRAME (d), w->frame) &&
- (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) &&
- EQ (DEVICE_CONSOLE (d), Vselected_console) &&
- XDEVICE (CONSOLE_SELECTED_DEVICE (XCONSOLE (DEVICE_CONSOLE (d)))) == d )
- ? BYTE_BUF_PT (b)
- : byte_marker_position (w->pointm[type]));
- EMACS_INT line;
-
- line = buffer_line_number (b, pos, 1, 1);
-
- {
- static Ibyte window_line_number_buf[DECIMAL_PRINT_SIZE (Fixnum)];
-
- fixnum_to_string (window_line_number_buf, sizeof (window_line_number_buf),
- line + 1, 10, Qnil);
-
- return window_line_number_buf;
- }
-}
-
-
/* Given a character representing an object in a modeline
specification, return a string (stored into the global array
`mode_spec_ibyte_string') with the information that object
@@ -7393,7 +7387,17 @@
/* print the current line number */
case 'l':
- str = (const Ascbyte *) window_line_number (w, type);
+ {
+ Bytebpos pos = (w == XWINDOW (Fselected_window (Qnil)))
+ ? BYTE_BUF_PT (b) : byte_marker_position (w->pointm[type]);
+ Charcount line = buffer_line_number (b, pos, 1, 1) + 1;
+ Ibyte buf[DECIMAL_PRINT_SIZE (line)];
+
+ Dynarr_add_many (mode_spec_ibyte_string, buf,
+ fixnum_to_string (buf, sizeof (buf), line + 1, 10,
+ Qnil));
+ goto decode_mode_spec_done;
+ }
break;
/* print value of mode-name (obsolete) */
@@ -7481,40 +7485,38 @@
/* print percent of buffer above top of window, or Top, Bot or All */
case 'p':
{
- Charbpos pos = marker_position (w->start[type]);
+ Bytebpos pos = byte_marker_position (w->start[type]);
/* This had better be while the desired lines are being done. */
if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
{
- if (pos <= BUF_BEGV (b))
+ if (pos <= BYTE_BUF_BEGV (b))
str = "All";
else
str = "Bottom";
}
- else if (pos <= BUF_BEGV (b))
+ else if (pos <= BYTE_BUF_BEGV (b))
str = "Top";
else
{
- /* This hard limit is ok since the string it will hold has a
- fixed maximum length of 3. But just to be safe... */
- Ascbyte buf[10];
- Charcount chars = pos - BUF_BEGV (b);
- Charcount total = BUF_ZV (b) - BUF_BEGV (b);
-
+ EMACS_UINT bytes = pos - BYTE_BUF_BEGV (b);
+ EMACS_UINT total = BYTE_BUF_ZV (b) - BYTE_BUF_BEGV (b);
/* Avoid overflow on big buffers */
- int percent = total > LONG_MAX/200 ?
- (chars + total/200) / (total / 100) :
- (chars * 100 + total/2) / total;
+ int percent = total > ((EMACS_UINT)(-1))/200 ?
+ (int) ((bytes + total/200) / (total / 100)):
+ (int) ((bytes * 100 + total/2) / total);
+ Ibyte buf[DECIMAL_PRINT_SIZE (percent)];
/* We can't normally display a 3-digit number, so get us a
2-digit number that is close. */
if (percent == 100)
percent = 99;
- sprintf (buf, "%d%%", percent);
- Dynarr_add_many (mode_spec_ibyte_string, (Ibyte *) buf,
- strlen (buf));
-
+ Dynarr_add_many (mode_spec_ibyte_string, buf,
+ fixnum_to_string (buf, sizeof (buf), percent,
+ 10, Vfixnum_to_majuscule_ascii));
+ Dynarr_add_literal_string (mode_spec_ibyte_string, "%");
+
goto decode_mode_spec_done;
}
break;
@@ -7524,48 +7526,53 @@
Top, or print Bottom or All */
case 'P':
{
- Charbpos toppos = marker_position (w->start[type]);
Charbpos botpos = BUF_Z (b) - w->window_end_pos[type];
- /* botpos is only accurate as of the last redisplay, so we can
- only treat it as a hint. In particular, after erase-buffer,
- botpos may be negative. */
- if (botpos < toppos)
- botpos = toppos;
-
if (botpos >= BUF_ZV (b))
{
- if (toppos <= BUF_BEGV (b))
+ if (byte_marker_position (w->start[type]) <= BYTE_BUF_BEGV (b))
str = "All";
else
str = "Bottom";
}
else
{
- /* This hard limit is ok since the string it will hold has a
- fixed maximum length of around 6. But just to be safe... */
- Ascbyte buf[10];
- Charcount chars = botpos - BUF_BEGV (b);
- Charcount total = BUF_ZV (b) - BUF_BEGV (b);
+ EMACS_UINT bytes, total = BYTE_BUF_ZV (b) - BYTE_BUF_BEGV (b);
+ Bytebpos toppos = byte_marker_position (w->start[type]);
+ int percent;
+ Ibyte buf[DECIMAL_PRINT_SIZE (percent)];
+
+ /* botpos is only accurate as of the last redisplay, so we can only
+ treat it as a hint. In particular, after erase-buffer, botpos
+ may be negative. This is also why the byte-char sloppiness is OK
+ in this specific instance. */
+
+ if (botpos < toppos)
+ {
+ botpos = (Charbpos) toppos;
+ }
+
+ bytes = (EMACS_UINT)(botpos) - BYTE_BUF_BEGV (b);
/* Avoid overflow on big buffers */
- int percent = total > LONG_MAX/200 ?
- (chars + total/200) / (total / 100) :
- (chars * 100 + total/2) / max (total, 1);
+ percent = total > ((EMACS_UINT)(-1))/200 ?
+ (int)((bytes + total/200) / (total / 100)) :
+ (int)((bytes * 100 + total/2) / max (total, 1));
/* We can't normally display a 3-digit number, so get us a
2-digit number that is close. */
if (percent == 100)
percent = 99;
- if (toppos <= BUF_BEGV (b))
- sprintf (buf, "Top%d%%", percent);
- else
- sprintf (buf, "%d%%", percent);
-
- Dynarr_add_many (mode_spec_ibyte_string, (Ibyte *) buf,
- strlen (buf));
-
+ if (toppos <= BYTE_BUF_BEGV (b))
+ {
+ Dynarr_add_literal_string (mode_spec_ibyte_string, "Top");
+ }
+
+ Dynarr_add_many (mode_spec_ibyte_string, buf,
+ fixnum_to_string (buf, sizeof (buf), percent,
+ 10, Vfixnum_to_majuscule_ascii));
+ Dynarr_add_literal_string (mode_spec_ibyte_string, "%");
goto decode_mode_spec_done;
}
break;
--
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)