APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1537221545 -3600
#      Mon Sep 17 22:59:05 2018 +0100
# Node ID 0f7b7204a7ff9acfa1ad4205b3d14c7ffff80375
# Parent  073c3792b109212ab00875dba328668d20436e40
Remove needless byte-char conversion in redisplay, line-number.c
src/ChangeLog addition:
2018-09-17  Aidan Kehoe  <kehoea(a)parhasard.net>
	* buffer.c (Fline_number):
	Adjust the call to buffer_line_number() here to use the Bytebpos.
	* insdel.c (buffer_insert_string_1):
	Adjust the call to insert_invalidate_line_number_cache() to use
	the Bytebpos.
	* insdel.c (buffer_delete_range):
	Adjust the call to delete_invalidate_line_number_cache() to use
	the Bytebpos.
	* line-number.c (narrow_line_number_cache):
	Check the byte positions rather than the character positions here,
	for consistency.
	* line-number.c (invalidate_line_number_cache):
	Now POS is a bytebpos, use byte_marker_position(), rather than
	marker_position(), so that inserting a newline is no longer O(S),
	where S is the number of entries in the line number cache.
	* line-number.c (insert_invalidate_line_number_cache):
	Take FROM and TO as byte rather than character positions.
	* line-number.c (delete_invalidate_line_number_cache):
	Ditto.
	* line-number.c (get_nearest_line_number):
	Take BEG and POS as byte rather than character positions.
	* line-number.c (add_position_to_cache):
	Take POS as a byte position, which allows us to call
	set_byte_marker_position() on our Fmake_marker() argument, an O(1)
	operation.
	* line-number.c (buffer_line_number):
	Take POS as a byte position here.
	* line-number.h:
	* line-number.h (buffer_line_number):
	* line-number.h (insert_invalidate_line_number_cache):
	* line-number.h (delete_invalidate_line_number_cache):
	Update the declaration for these functions to reflect Bytebpos
	rather than Charbpos arguments.
	* lisp.h:
	Make byte_scan_buffer() available here.
	* redisplay.c (window_line_number):
	Adjust this so we're not doing marker_position() on the saved
	point marker, potentially O(N) on the position in the buffer.
	* search.c (byte_scan_buffer):
	Make this non-static (ideally we would delete scan_buffer()
	entirely).
diff -r 073c3792b109 -r 0f7b7204a7ff src/ChangeLog
--- a/src/ChangeLog	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/ChangeLog	Mon Sep 17 22:59:05 2018 +0100
@@ -1,3 +1,47 @@
+2018-09-17  Aidan Kehoe  <kehoea(a)parhasard.net>
+
+	* buffer.c (Fline_number):
+	Adjust the call to buffer_line_number() here to use the Bytebpos.
+	* insdel.c (buffer_insert_string_1):
+	Adjust the call to insert_invalidate_line_number_cache() to use
+	the Bytebpos.
+	* insdel.c (buffer_delete_range):
+	Adjust the call to delete_invalidate_line_number_cache() to use
+	the Bytebpos.
+	* line-number.c (narrow_line_number_cache):
+	Check the byte positions rather than the character positions here,
+	for consistency.
+	* line-number.c (invalidate_line_number_cache):
+	Now POS is a bytebpos, use byte_marker_position(), rather than
+	marker_position(), so that inserting a newline is no longer O(S),
+	where S is the number of entries in the line number cache.
+	* line-number.c (insert_invalidate_line_number_cache):
+	Take FROM and TO as byte rather than character positions.
+	* line-number.c (delete_invalidate_line_number_cache):
+	Ditto.
+	* line-number.c (get_nearest_line_number):
+	Take BEG and POS as byte rather than character positions.
+	* line-number.c (add_position_to_cache):
+	Take POS as a byte position, which allows us to call
+	set_byte_marker_position() on our Fmake_marker() argument, an O(1)
+	operation.
+	* line-number.c (buffer_line_number):
+	Take POS as a byte position here.
+	* line-number.h:
+	* line-number.h (buffer_line_number):
+	* line-number.h (insert_invalidate_line_number_cache):
+	* line-number.h (delete_invalidate_line_number_cache):
+	Update the declaration for these functions to reflect Bytebpos
+	rather than Charbpos arguments.
+	* lisp.h:
+	Make byte_scan_buffer() available here.
+	* redisplay.c (window_line_number):
+	Adjust this so we're not doing marker_position() on the saved
+	point marker, potentially O(N) on the position in the buffer.
+	* search.c (byte_scan_buffer):
+	Make this non-static (ideally we would delete scan_buffer()
+	entirely).
+
 2018-09-17  Aidan Kehoe  <kehoea(a)parhasard.net>
 
 	* editfns.c (byte_beginning_of_line_p): New. Byte-oriented
diff -r 073c3792b109 -r 0f7b7204a7ff src/buffer.c
--- a/src/buffer.c	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/buffer.c	Mon Sep 17 22:59:05 2018 +0100
@@ -1825,8 +1825,8 @@
        (position, respect_narrowing, buffer_))
 {
   struct buffer *buf = decode_buffer (buffer_, 0);
-  Charbpos pos = (NILP (position) ? BUF_PT (buf) :
-		  get_buffer_pos_char (buf, position, GB_COERCE_RANGE));
+  Bytebpos pos = (NILP (position) ? BYTE_BUF_PT (buf) :
+		  get_buffer_pos_byte (buf, position, GB_COERCE_RANGE));
 
   return make_fixnum (buffer_line_number (buf, pos, 1,
                                           !NILP (respect_narrowing)) + 1);
diff -r 073c3792b109 -r 0f7b7204a7ff src/insdel.c
--- a/src/insdel.c	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/insdel.c	Mon Sep 17 22:59:05 2018 +0100
@@ -1160,7 +1160,8 @@
      in a consistent state.  Following code puts buffer in an inconsistent
      state and can be considered a "critical section". */
   
-  insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length);
+  insert_invalidate_line_number_cache (buf, bytepos, nonreloc + offset,
+                                       length);
 
   MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
     {
@@ -1445,7 +1446,7 @@
 	}
     }
 
-  delete_invalidate_line_number_cache (buf, from, to);
+  delete_invalidate_line_number_cache (buf, byte_from, byte_to);
 
 #ifdef MULE
   /* Update our count of ASCII, 8-bit and 16-bit chars and the
diff -r 073c3792b109 -r 0f7b7204a7ff src/line-number.c
--- a/src/line-number.c	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/line-number.c	Mon Sep 17 22:59:05 2018 +0100
@@ -103,7 +103,7 @@
   if (NILP (b->text->line_number_cache))
     return;
 
-  if (BUF_BEG (b) == BUF_BEGV (b))
+  if (BYTE_BUF_BEG (b) == BYTE_BUF_BEGV (b))
     /* The is the case Fwiden and save_restriction_restore.  Since we
        know the correct value, we can update it now.  */
     LINE_NUMBER_BEGV (b) = Qzero;
@@ -116,7 +116,7 @@
 
 /* Invalidate the line number cache positions that lie after POS. */
 static void
-invalidate_line_number_cache (struct buffer *b, Charbpos pos)
+invalidate_line_number_cache (struct buffer *b, Bytebpos pos)
 {
   EMACS_INT i, j;
   Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
@@ -134,7 +134,7 @@
 	 at point, which is way losing.  Isn't there a way to make a
 	 marker impervious to Finsert_before_markers()??  Maybe I
 	 should convert the code to use extents.  */
-      if (marker_position (XCAR (ring[i])) >= pos)
+      if (byte_marker_position (XCAR (ring[i])) >= pos)
 	{
 	  /* Get the marker out of the way.  */
 	  Fset_marker (XCAR (ring[i]), Qnil, Qnil);
@@ -155,7 +155,7 @@
 
    This will do nothing if the cache is uninitialized.  */
 void
-insert_invalidate_line_number_cache (struct buffer *b, Charbpos pos,
+insert_invalidate_line_number_cache (struct buffer *b, Bytebpos pos,
 				     const Ibyte *nonreloc, Bytecount length)
 {
   if (NILP (b->text->line_number_cache))
@@ -177,7 +177,8 @@
 
    This will do nothing if the cache is uninitialized.  */
 void
-delete_invalidate_line_number_cache (struct buffer *b, Charbpos from, Charbpos to)
+delete_invalidate_line_number_cache (struct buffer *b, Bytebpos from,
+                                     Bytebpos to)
 {
   if (NILP (b->text->line_number_cache))
     return;
@@ -187,7 +188,7 @@
   else
     {
       EMACS_INT shortage;
-      scan_buffer (b, '\n', from, to, 1, &shortage, 0);
+      byte_scan_buffer (b, '\n', from, to, 1, &shortage, 0);
       if (!shortage)
 	invalidate_line_number_cache (b, from);
     }
@@ -202,12 +203,12 @@
    BEG will be BUF_BEGV, and *LINE will be XFIXNUM (LINE_NUMBER_BEGV).
    This will initialize the cache, if necessary.  */
 static void
-get_nearest_line_number (struct buffer *b, Charbpos *beg, Charbpos pos,
+get_nearest_line_number (struct buffer *b, Bytebpos *beg, Bytebpos pos,
 			 EMACS_INT *line)
 {
   EMACS_INT i;
   Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
-  Charcount length = pos - *beg;
+  Bytecount length = pos - *beg;
 
   if (length < 0)
     length = -length;
@@ -215,8 +216,8 @@
   /* Find the ring entry closest to POS, if it is closer than BEG. */
   for (i = 0; i < LINE_NUMBER_RING_SIZE && CONSP (ring[i]); i++)
     {
-      Charbpos newpos = marker_position (XCAR (ring[i]));
-      Charcount howfar = newpos - pos;
+      Bytebpos newpos = byte_marker_position (XCAR (ring[i]));
+      Bytecount howfar = newpos - pos;
       if (howfar < 0)
 	howfar = -howfar;
       if (howfar < length)
@@ -230,7 +231,7 @@
 
 /* Add a (POS . LINE) pair to the ring, and rotate it. */
 static void
-add_position_to_cache (struct buffer *b, Charbpos pos, EMACS_INT line)
+add_position_to_cache (struct buffer *b, Bytebpos pos, EMACS_INT line)
 {
   Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
   int i = LINE_NUMBER_RING_SIZE - 1;
@@ -244,8 +245,8 @@
     ring[i] = ring[i - 1];
 
   /* ...and update it. */
-  ring[0] = Fcons (Fset_marker (Fmake_marker (), make_fixnum (pos),
-				wrap_buffer (b)),
+  ring[0] = Fcons (set_byte_marker_position (Fmake_marker (), pos,
+                                             wrap_buffer (b)),
 		   make_fixnum (line));
 }
 
@@ -266,17 +267,17 @@
    If the calculation (with or without the cache lookup) required more
    than LINE_NUMBER_FAR characters of traversal, update the cache.  */
 EMACS_INT
-buffer_line_number (struct buffer *b, Charbpos pos, Boolint cachep,
+buffer_line_number (struct buffer *b, Bytebpos pos, Boolint cachep,
                     Boolint respect_narrowing)
 {
-  Charbpos beg = respect_narrowing ? BUF_BEGV (b) : BUF_BEG (b);
+  Bytebpos beg = respect_narrowing ? BYTE_BUF_BEGV (b) : BYTE_BUF_BEG (b);
   EMACS_INT cached_lines = 0;
   EMACS_INT shortage, line;
 
   if ((pos > beg ? pos - beg : beg - pos) <= LINE_NUMBER_FAR)
     cachep = 0;
 
-  if (cachep && (respect_narrowing || BUF_BEG (b) == BUF_BEGV (b)))
+  if (cachep && (respect_narrowing || BYTE_BUF_BEG (b) == BYTE_BUF_BEGV (b)))
     {
       if (NILP (b->text->line_number_cache))
 	allocate_line_number_cache (b);
@@ -286,13 +287,13 @@
 	  LINE_NUMBER_BEGV (b) = Qzero;
 	  /* #### This has a side-effect of changing the cache.  */
 	  LINE_NUMBER_BEGV (b) =
-	    make_fixnum (buffer_line_number (b, BUF_BEGV (b), 1, 0));
+	    make_fixnum (buffer_line_number (b, BYTE_BUF_BEGV (b), 1, 0));
 	}
       cached_lines = XFIXNUM (LINE_NUMBER_BEGV (b));
       get_nearest_line_number (b, &beg, pos, &cached_lines);
     }
 
-  scan_buffer (b, '\n', beg, pos,
+  byte_scan_buffer (b, '\n', beg, pos,
                pos > beg ? MOST_POSITIVE_FIXNUM : -MOST_POSITIVE_FIXNUM,
 	       &shortage, 0);
 
diff -r 073c3792b109 -r 0f7b7204a7ff src/line-number.h
--- a/src/line-number.h	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/line-number.h	Mon Sep 17 22:59:05 2018 +0100
@@ -21,10 +21,10 @@
 /* Synched up with: Not in FSF. */
 
 void narrow_line_number_cache (struct buffer *);
-void insert_invalidate_line_number_cache (struct buffer *, Charbpos,
+void insert_invalidate_line_number_cache (struct buffer *, Bytebpos,
 					  const Ibyte *, Bytecount);
-void delete_invalidate_line_number_cache (struct buffer *, Charbpos, Charbpos);
+void delete_invalidate_line_number_cache (struct buffer *, Bytebpos, Bytebpos);
 
-EMACS_INT buffer_line_number (struct buffer *, Charbpos, int, Boolint);
+EMACS_INT buffer_line_number (struct buffer *, Bytebpos, int, Boolint);
 
 #endif /* INCLUDED_line_number_h_ */
diff -r 073c3792b109 -r 0f7b7204a7ff src/lisp.h
--- a/src/lisp.h	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/lisp.h	Mon Sep 17 22:59:05 2018 +0100
@@ -6009,6 +6009,9 @@
 struct re_registers;
 Charbpos scan_buffer (struct buffer *, Ichar, Charbpos, Charbpos, EMACS_INT,
 		      EMACS_INT *, int);
+Bytebpos byte_scan_buffer (struct buffer *, Ichar, Bytebpos, Bytebpos ,
+                           EMACS_INT, EMACS_INT *, int);
+
 Charbpos find_next_newline (struct buffer *, Charbpos, int);
 Charbpos find_next_newline_no_quit (struct buffer *, Charbpos, int);
 Bytebpos byte_find_next_newline_no_quit (struct buffer *, Bytebpos, int);
diff -r 073c3792b109 -r 0f7b7204a7ff src/redisplay.c
--- a/src/redisplay.c	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/redisplay.c	Mon Sep 17 22:59:05 2018 +0100
@@ -7287,13 +7287,13 @@
   /* 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 */
-  Charbpos pos =
+  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 )
-     ? BUF_PT (b)
-     : marker_position (w->pointm[type]));
+     ? BYTE_BUF_PT (b)
+     : byte_marker_position (w->pointm[type]));
   EMACS_INT line;
 
   line = buffer_line_number (b, pos, 1, 1);
diff -r 073c3792b109 -r 0f7b7204a7ff src/search.c
--- a/src/search.c	Mon Sep 17 20:50:35 2018 +0100
+++ b/src/search.c	Mon Sep 17 22:59:05 2018 +0100
@@ -702,7 +702,7 @@
 
    If ALLOW_QUIT is non-zero, call QUIT periodically. */
 
-static Bytebpos
+Bytebpos
 byte_scan_buffer (struct buffer *buf, Ichar target, Bytebpos st, Bytebpos en,
 		  EMACS_INT count, EMACS_INT *shortage, int allow_quit)
 {
-- 
‘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)