patches: fix O(buffer) cache invalidation caused by font-lock
BUF_CHARS_MODIFF fix — the core performance regression: ensureTextCache checked BUF_MODIFF which font-lock bumps on every redisplay. Each cursor movement in a large file triggered full buffer rebuild. Now uses BUF_CHARS_MODIFF (changes only on char insert/delete).
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
From 8ef9b7f50f9ebb1c23e8e8bf2b5158e073b35e37 Mon Sep 17 00:00:00 2001
|
From b38d702cb19f2b7c36d88d7e397323ea1aca1c9b Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 22:39:35 +0100
|
Date: Sat, 28 Feb 2026 22:39:35 +0100
|
||||||
Subject: [PATCH 1/9] ns: integrate with macOS Zoom for cursor tracking
|
Subject: [PATCH 01/10] ns: integrate with macOS Zoom for cursor tracking
|
||||||
|
|
||||||
Inform macOS Zoom of the text cursor position so the zoomed viewport
|
Inform macOS Zoom of the text cursor position so the zoomed viewport
|
||||||
follows keyboard focus in Emacs.
|
follows keyboard focus in Emacs.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 6e8cc407d6f407c2201a35438bab60b112a11c9e Mon Sep 17 00:00:00 2001
|
From e6800d12d350def06dd6475fcb807ceaf7f82e02 Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 2/9] ns: add accessibility base classes and text extraction
|
Subject: [PATCH 02/10] ns: add accessibility base classes and text extraction
|
||||||
|
|
||||||
Add the foundation for macOS VoiceOver accessibility in the NS
|
Add the foundation for macOS VoiceOver accessibility in the NS
|
||||||
(Cocoa) port. No existing code paths are modified.
|
(Cocoa) port. No existing code paths are modified.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From aa788f7df93a3307f52cf10d16fe4af10eaae03d Mon Sep 17 00:00:00 2001
|
From d3dd16835ff6b7456f987893ef610e3847a92fde Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 3/9] ns: implement buffer accessibility element (core
|
Subject: [PATCH 03/10] ns: implement buffer accessibility element (core
|
||||||
protocol)
|
protocol)
|
||||||
|
|
||||||
Implement the NSAccessibility text protocol for Emacs buffer windows.
|
Implement the NSAccessibility text protocol for Emacs buffer windows.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 3da80e1c56c7270d458dfacd45e78e111359f526 Mon Sep 17 00:00:00 2001
|
From 601df3982e20e60f041fa2658aa7ef1efb69939b Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 4/9] ns: add buffer notification dispatch and mode-line
|
Subject: [PATCH 04/10] ns: add buffer notification dispatch and mode-line
|
||||||
element
|
element
|
||||||
|
|
||||||
Add VoiceOver notification methods and mode-line readout.
|
Add VoiceOver notification methods and mode-line readout.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 9e13d137b009d4c2ecd2b6f55afa672637e8d62c Mon Sep 17 00:00:00 2001
|
From 8c67a2b5a89ac302cbac91790fdfb6827b74285a Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 5/9] ns: add interactive span elements for Tab navigation
|
Subject: [PATCH 05/10] ns: add interactive span elements for Tab navigation
|
||||||
|
|
||||||
* src/nsterm.m (ns_ax_scan_interactive_spans): New function.
|
* src/nsterm.m (ns_ax_scan_interactive_spans): New function.
|
||||||
(EmacsAccessibilityInteractiveSpan): Implement AXButton/AXLink
|
(EmacsAccessibilityInteractiveSpan): Implement AXButton/AXLink
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
From 8d882bfbad959b55915da0a43897acf2aca3b2ed Mon Sep 17 00:00:00 2001
|
From 3237374282389cd61bcd99beed187ec75d1b06fc Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 6/9] ns: integrate accessibility with EmacsView and redisplay
|
Subject: [PATCH 06/10] ns: integrate accessibility with EmacsView and
|
||||||
|
redisplay
|
||||||
|
|
||||||
Wire the accessibility infrastructure into EmacsView and the
|
Wire the accessibility infrastructure into EmacsView and the
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 6eddc6fb5933f561e7459198e403519d1c7eecd0 Mon Sep 17 00:00:00 2001
|
From e2b76f1850489e8188236bed10e4d7f28e5cde2b Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
||||||
Subject: [PATCH 7/9] doc: add VoiceOver accessibility section to macOS
|
Subject: [PATCH 07/10] doc: add VoiceOver accessibility section to macOS
|
||||||
appendix
|
appendix
|
||||||
|
|
||||||
* doc/emacs/macos.texi (VoiceOver Accessibility): New node. Document
|
* doc/emacs/macos.texi (VoiceOver Accessibility): New node. Document
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
From 5cd1b5f46e670f031ce5fcca2d9312059d6efa87 Mon Sep 17 00:00:00 2001
|
From 3e868d0234c858fa20588e664354685ef8b08576 Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 14:46:25 +0100
|
Date: Sat, 28 Feb 2026 14:46:25 +0100
|
||||||
Subject: [PATCH 8/9] ns: announce overlay completion candidates for VoiceOver
|
Subject: [PATCH 08/10] ns: announce overlay completion candidates for
|
||||||
|
VoiceOver
|
||||||
|
|
||||||
Completion frameworks such as Vertico, Ivy, and Icomplete render
|
Completion frameworks such as Vertico, Ivy, and Icomplete render
|
||||||
candidates via overlay before-string/after-string properties rather
|
candidates via overlay before-string/after-string properties rather
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 5db9f29f8a8fee97f01ae716f36f37c605dbd70d Mon Sep 17 00:00:00 2001
|
From 5aba3491f8f5268f2e6093003b79fe69e7932a4b Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Sat, 28 Feb 2026 16:01:29 +0100
|
Date: Sat, 28 Feb 2026 16:01:29 +0100
|
||||||
Subject: [PATCH 9/9] ns: announce child frame completion candidates for
|
Subject: [PATCH 09/10] ns: announce child frame completion candidates for
|
||||||
VoiceOver
|
VoiceOver
|
||||||
|
|
||||||
Completion frameworks such as Corfu, Company-box, and similar
|
Completion frameworks such as Corfu, Company-box, and similar
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
From 4b739781a019fd1ad5b6ac1c9c12dc62e2c82ec3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daneel <daneel@sukany.cz>
|
||||||
|
Date: Sun, 1 Mar 2026 04:56:16 +0100
|
||||||
|
Subject: [PATCH 10/10] perf: use BUF_CHARS_MODIFF for AX text cache validity
|
||||||
|
in ensureTextCache
|
||||||
|
|
||||||
|
The cache validity check in -[EmacsAccessibilityBuffer ensureTextCache]
|
||||||
|
used BUF_MODIFF, which is bumped by every text-property change ---
|
||||||
|
including face applications by font-lock on each redisplay cycle.
|
||||||
|
Since the AX text value contains only characters (no face or property
|
||||||
|
data), property-only changes do not affect it. Rebuilding the full
|
||||||
|
buffer text on each font-lock pass is O(buffer-size) per redisplay,
|
||||||
|
causing progressive slowdown proportional to how far the cursor is
|
||||||
|
from the beginning of the file.
|
||||||
|
|
||||||
|
Switch to BUF_CHARS_MODIFF, which is bumped only when characters are
|
||||||
|
actually inserted or deleted. This matches the semantic of 'did the
|
||||||
|
text change' and is the approach used by WebKit and NSTextView.
|
||||||
|
|
||||||
|
BUF_OVERLAY_MODIFF is intentionally not tracked here (unchanged):
|
||||||
|
overlay content is handled by separate announcements in
|
||||||
|
postAccessibilityNotificationsForFrame, and including it in this
|
||||||
|
check would prevent those announcements from firing.
|
||||||
|
---
|
||||||
|
src/nsterm.m | 27 ++++++++++++++++++---------
|
||||||
|
1 file changed, 18 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||||
|
index 12c451b..e3f9466 100644
|
||||||
|
--- a/src/nsterm.m
|
||||||
|
+++ b/src/nsterm.m
|
||||||
|
@@ -8148,16 +8148,25 @@ - (void)ensureTextCache
|
||||||
|
if (!b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- ptrdiff_t modiff = BUF_MODIFF (b);
|
||||||
|
- ptrdiff_t pt = BUF_PT (b);
|
||||||
|
- NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
||||||
|
- /* Cache validity: track BUF_MODIFF and buffer narrowing.
|
||||||
|
+ /* Use BUF_CHARS_MODIFF, not BUF_MODIFF, for cache validity.
|
||||||
|
+ BUF_MODIFF is bumped by every text-property change, including
|
||||||
|
+ font-lock face applications on every redisplay. AX text contains
|
||||||
|
+ only characters, not face data, so property-only changes do not
|
||||||
|
+ affect the cached value. Rebuilding the full buffer text on
|
||||||
|
+ each font-lock pass is O(buffer-size) per redisplay --- this
|
||||||
|
+ causes progressive slowdown when scrolling through large files.
|
||||||
|
+ BUF_CHARS_MODIFF is bumped only on actual character insertions
|
||||||
|
+ and deletions, matching the semantic of "did the text change".
|
||||||
|
+ This is the pattern used by WebKit and NSTextView.
|
||||||
|
Do NOT track BUF_OVERLAY_MODIFF here --- overlay text is not
|
||||||
|
included in the cached AX text (it is handled separately via
|
||||||
|
- explicit announcements). Including overlay_modiff would
|
||||||
|
- silently update cachedOverlayModiff and prevent the
|
||||||
|
- notification dispatch from detecting overlay changes. */
|
||||||
|
- if (cachedText && cachedTextModiff == modiff
|
||||||
|
+ explicit announcements in postAccessibilityNotificationsForFrame).
|
||||||
|
+ Including overlay_modiff would silently update cachedOverlayModiff
|
||||||
|
+ and prevent the notification dispatch from detecting changes. */
|
||||||
|
+ ptrdiff_t chars_modiff = BUF_CHARS_MODIFF (b);
|
||||||
|
+ ptrdiff_t pt = BUF_PT (b);
|
||||||
|
+ NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
||||||
|
+ if (cachedText && cachedTextModiff == chars_modiff
|
||||||
|
&& cachedTextStart == BUF_BEGV (b)
|
||||||
|
&& pt >= cachedTextStart
|
||||||
|
&& (textLen == 0
|
||||||
|
@@ -8173,7 +8182,7 @@ included in the cached AX text (it is handled separately via
|
||||||
|
{
|
||||||
|
[cachedText release];
|
||||||
|
cachedText = [text retain];
|
||||||
|
- cachedTextModiff = modiff;
|
||||||
|
+ cachedTextModiff = chars_modiff;
|
||||||
|
cachedTextStart = start;
|
||||||
|
|
||||||
|
if (visibleRuns)
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
Reference in New Issue
Block a user