unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dmitry@gutov.dev>
To: Eli Zaretskii <eliz@gnu.org>, Steven Allen <steven@stebalien.com>
Cc: jporterbugs@gmail.com, 71525@debbugs.gnu.org
Subject: bug#71525: 30.0.50; Spin in delete-region/interval_deletion_adjustment Spin in delete-region/interval_deletion_adjustment)
Date: Fri, 14 Jun 2024 02:41:15 +0300	[thread overview]
Message-ID: <f8c96939-5a91-418f-83ad-0d7de40b115f@gutov.dev> (raw)
In-Reply-To: <d4beaef6-0417-43e1-95f2-e0f1fec9ad6a@gutov.dev>

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]

On 14/06/2024 00:47, Dmitry Gutov wrote:
> The thing is, decode_coding_c_string already calls 
> adjust_markers_for_insert through
> 
>    decode_coding_object->decode_coding->produce_chars->insert_from_gap
> 
> And the extra call moves the markers too far.
> 
> Unfortunately, it's called with BEFORE_MARKERS=nil, and the above call 
> chain makes it difficult to pass through the extra argument.

We can do it through the coding_system structure, though.

See attached. It fixes the freezes in my testing.

It seems like the least invasive possible fix, but better suggestions 
welcome.

[-- Attachment #2: dst_before_markers.diff --]
[-- Type: text/x-patch, Size: 6084 bytes --]

diff --git a/src/coding.c b/src/coding.c
index 5e4e92ea6e2..138aaa22e6a 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -5698,6 +5698,7 @@ setup_coding_system (Lisp_Object coding_system, struct coding_system *coding)
   coding->default_char = XFIXNUM (CODING_ATTR_DEFAULT_CHAR (attrs));
   coding->carryover_bytes = 0;
   coding->raw_destination = 0;
+  coding->dst_before_markers = 0;
 
   coding_type = CODING_ATTR_TYPE (attrs);
   if (EQ (coding_type, Qundecided))
@@ -7209,7 +7210,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 
   produced = dst - (coding->destination + coding->produced);
   if (BUFFERP (coding->dst_object) && produced_chars > 0)
-    insert_from_gap (produced_chars, produced, 0);
+    insert_from_gap (produced_chars, produced, 0, coding->dst_before_markers);
   coding->produced += produced;
   coding->produced_char += produced_chars;
   return carryover;
@@ -7814,7 +7815,7 @@ encode_coding (struct coding_system *coding)
   } while (coding->consumed_char < coding->src_chars);
 
   if (BUFFERP (coding->dst_object) && coding->produced_char > 0)
-    insert_from_gap (coding->produced_char, coding->produced, 0);
+    insert_from_gap (coding->produced_char, coding->produced, 0, coding->dst_before_markers);
 
   SAFE_FREE ();
 }
@@ -8008,7 +8009,7 @@ decode_coding_gap (struct coding_system *coding, ptrdiff_t bytes)
 	    }
 	  coding->produced = bytes;
 	  coding->produced_char = chars;
-	  insert_from_gap (chars, bytes, 1);
+	  insert_from_gap (chars, bytes, 1, coding->dst_before_markers);
 	  return;
 	}
     }
@@ -9980,7 +9981,7 @@ encode_string_utf_8 (Lisp_Object string, Lisp_Object buffer,
       struct buffer *oldb = current_buffer;
 
       current_buffer = XBUFFER (buffer);
-      insert_from_gap (outbytes, outbytes, false);
+      insert_from_gap (outbytes, outbytes, false, false);
       current_buffer = oldb;
     }
   return val;
@@ -10290,7 +10291,7 @@ #define UTF_8_SEQUENCE_LENGTH(c)	\
       struct buffer *oldb = current_buffer;
 
       current_buffer = XBUFFER (buffer);
-      insert_from_gap (outchars, outbytes, false);
+      insert_from_gap (outchars, outbytes, false, false);
       current_buffer = oldb;
     }
   return val;
diff --git a/src/coding.h b/src/coding.h
index 8905e36838d..2e031d8cc55 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -428,6 +428,9 @@ #define CODING_MODE_SAFE_ENCODING		0x10
   /* Set to true if charbuf contains an annotation.  */
   bool_bf annotated : 1;
 
+  /* True to insert before markers in the DST_OBJECT buffer.  */
+  bool_bf dst_before_markers : 1;
+
   /* Used internally in coding.c.  See the comment of detect_ascii.  */
   unsigned eol_seen : 3;
 
diff --git a/src/decompress.c b/src/decompress.c
index fcdbb40fc90..6c342e54355 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -310,7 +310,7 @@ DEFUN ("zlib-decompress-region", Fzlib_decompress_region,
       inflate_status = inflate (&stream, Z_NO_FLUSH);
       pos_byte += avail_in - stream.avail_in;
       decompressed = avail_out - stream.avail_out;
-      insert_from_gap (decompressed, decompressed, 0);
+      insert_from_gap (decompressed, decompressed, 0, false);
       unwind_data.nbytes += decompressed;
       maybe_quit ();
     }
diff --git a/src/insdel.c b/src/insdel.c
index fbf71e1e595..8f8e7b7d71d 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1129,10 +1129,12 @@ insert_from_gap_1 (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
 
 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
    starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at
-   GPT_ADDR (if not text_at_gap_tail).  */
+   GPT_ADDR (if not text_at_gap_tail).
+
+  If BEFORE_MARKERS is true, insert before markers. */
 
 void
-insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
+insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail, bool before_markers)
 {
   ptrdiff_t ins_charpos = GPT, ins_bytepos = GPT_BYTE;
 
@@ -1151,7 +1153,7 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
   insert_from_gap_1 (nchars, nbytes, text_at_gap_tail);
 
   adjust_markers_for_insert (ins_charpos, ins_bytepos,
-			     ins_charpos + nchars, ins_bytepos + nbytes, false);
+			     ins_charpos + nchars, ins_bytepos + nbytes, before_markers);
 
   if (buffer_intervals (current_buffer))
     {
diff --git a/src/lisp.h b/src/lisp.h
index 21dada59132..2c3c4e0ba87 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4372,7 +4372,8 @@ verify (FLT_RADIX == 2 || FLT_RADIX == 16);
 extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t,
 			   bool, bool, bool);
 extern void insert_from_gap_1 (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail);
-extern void insert_from_gap (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail);
+extern void insert_from_gap (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail,
+			     bool before_markers);
 extern void insert_from_string (Lisp_Object, ptrdiff_t, ptrdiff_t,
 				ptrdiff_t, ptrdiff_t, bool);
 extern void insert_from_buffer (struct buffer *, ptrdiff_t, ptrdiff_t, bool);
diff --git a/src/process.c b/src/process.c
index eb526311c53..7000b51775c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -6415,6 +6415,7 @@ read_and_insert_process_output (struct Lisp_Process *p, char *buf,
       specpdl_ref count1 = SPECPDL_INDEX ();
 
       XSETBUFFER (curbuf, current_buffer);
+      process_coding->dst_before_markers = true;
       /* We cannot allow after-change-functions be run
 	 during decoding, because that might modify the
 	 buffer, while we rely on process_coding.produced to
@@ -6423,9 +6424,6 @@ read_and_insert_process_output (struct Lisp_Process *p, char *buf,
       specbind (Qinhibit_modification_hooks, Qt);
       decode_coding_c_string (process_coding,
 			      (unsigned char *) buf, nread, curbuf);
-      adjust_markers_for_insert (PT, PT_BYTE,
-				 PT + process_coding->produced_char,
-				 PT_BYTE + process_coding->produced, true);
       unbind_to (count1, Qnil);
 
       read_process_output_set_last_coding_system (p, process_coding);

  reply	other threads:[~2024-06-13 23:41 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-12 19:20 bug#71525: 30.0.50; Spin in delete-region/interval_deletion_adjustment Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
     [not found] ` <handler.71525.B.171822007123849.ack@debbugs.gnu.org>
2024-06-13  5:14   ` bug#71525: Acknowledgement (30.0.50; Spin in delete-region/interval_deletion_adjustment) Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13  5:52     ` bug#71525: 30.0.50; Spin in delete-region/interval_deletion_adjustment " Eli Zaretskii
2024-06-13 15:32       ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13 15:52         ` Eli Zaretskii
2024-06-13 16:00           ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13 16:06             ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13 16:31               ` Eli Zaretskii
2024-06-13 21:47                 ` Dmitry Gutov
2024-06-13 23:41                   ` Dmitry Gutov [this message]
2024-06-14  7:13                     ` Eli Zaretskii
2024-06-14 16:51                       ` Dmitry Gutov
2024-06-14 18:14                         ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-14 18:17                       ` Dmitry Gutov
2024-06-14 18:46                         ` Eli Zaretskii
2024-06-14 19:13                           ` Dmitry Gutov
2024-06-13 19:18           ` Jim Porter
2024-06-13 19:42             ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13  5:49 ` bug#71525: 30.0.50; Spin in delete-region/interval_deletion_adjustment Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f8c96939-5a91-418f-83ad-0d7de40b115f@gutov.dev \
    --to=dmitry@gutov.dev \
    --cc=71525@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=jporterbugs@gmail.com \
    --cc=steven@stebalien.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).