aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatt Armstrong2022-10-19 13:42:35 -0700
committerStefan Monnier2022-10-19 21:35:09 -0400
commit06252617b2c4cc9bcdd9407f1e709a7e0908cf27 (patch)
tree494a0f21b5f87949886c57bfba87bd4ab013f49b /src
parent8159d8b1a71dd59e31060f00b2abe20ad9d1f924 (diff)
downloademacs-06252617b2c4cc9bcdd9407f1e709a7e0908cf27.tar.gz
emacs-06252617b2c4cc9bcdd9407f1e709a7e0908cf27.zip
Revert "mark_overlays: Use the normal ITREE_FOREACH"
This reverts commit b8fbd42f0a7caa4cd9e2d50dd4e4b2101ac78acd, with edits. * src/alloc.c (mark_overlays): restore function. (mark_buffer): Call it, not ITREE_FOREACH. (garbage_collect): eassert (!itree_busy_p ()). * src/itree.h: Comment tweak: explain why GC is considered risky. It isn't that GC itself is risky, it is that GC can call ELisp by way of a hook, and running ELisp during iteration is risks nested iteration.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c22
-rw-r--r--src/itree.h3
2 files changed, 21 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 00f2991f250..d7e0a99ffe7 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6279,6 +6279,11 @@ garbage_collect (void)
6279 image_prune_animation_caches (false); 6279 image_prune_animation_caches (false);
6280#endif 6280#endif
6281 6281
6282 /* ELisp code run by `gc-post-hook' could result in itree iteration,
6283 which must not happen while the itree is already busy. See
6284 bug#58639. */
6285 eassert (!itree_iterator_busy_p ());
6286
6282 if (!NILP (Vpost_gc_hook)) 6287 if (!NILP (Vpost_gc_hook))
6283 { 6288 {
6284 specpdl_ref gc_count = inhibit_garbage_collection (); 6289 specpdl_ref gc_count = inhibit_garbage_collection ();
@@ -6510,6 +6515,18 @@ mark_overlay (struct Lisp_Overlay *ov)
6510 mark_object (ov->plist); 6515 mark_object (ov->plist);
6511} 6516}
6512 6517
6518/* Mark the overlay subtree rooted at NODE. */
6519
6520static void
6521mark_overlays (struct interval_node *node)
6522{
6523 if (node == NULL)
6524 return;
6525 mark_object (node->data);
6526 mark_overlays (node->left);
6527 mark_overlays (node->right);
6528}
6529
6513/* Mark Lisp_Objects and special pointers in BUFFER. */ 6530/* Mark Lisp_Objects and special pointers in BUFFER. */
6514 6531
6515static void 6532static void
@@ -6531,9 +6548,8 @@ mark_buffer (struct buffer *buffer)
6531 if (!BUFFER_LIVE_P (buffer)) 6548 if (!BUFFER_LIVE_P (buffer))
6532 mark_object (BVAR (buffer, undo_list)); 6549 mark_object (BVAR (buffer, undo_list));
6533 6550
6534 struct interval_node *node; 6551 if (buffer->overlays)
6535 ITREE_FOREACH (node, buffer->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING) 6552 mark_overlays (buffer->overlays->root);
6536 mark_object (node->data);
6537 6553
6538 /* If this is an indirect buffer, mark its base buffer. */ 6554 /* If this is an indirect buffer, mark its base buffer. */
6539 if (buffer->base_buffer && 6555 if (buffer->base_buffer &&
diff --git a/src/itree.h b/src/itree.h
index 8d33ef223b5..b0f7a1d193b 100644
--- a/src/itree.h
+++ b/src/itree.h
@@ -149,7 +149,8 @@ struct interval_node *itree_iterator_next (struct itree_iterator *);
149 it is cheap a pure. 149 it is cheap a pure.
150 - Only a single iteration can happen at a time, so make sure none of the 150 - Only a single iteration can happen at a time, so make sure none of the
151 code within the loop can start another tree iteration, i.e. it shouldn't 151 code within the loop can start another tree iteration, i.e. it shouldn't
152 be able to run ELisp code (or GC for that matter). 152 be able to run ELisp code, nor GC since GC can run ELisp by way
153 of `post-gc-hook`.
153 - If you need to exit the loop early, you *have* to call `ITREE_ABORT` 154 - If you need to exit the loop early, you *have* to call `ITREE_ABORT`
154 just before exiting (e.g. with `break` or `return`). 155 just before exiting (e.g. with `break` or `return`).
155 - Non-local exits are not supported within the body of the loop. 156 - Non-local exits are not supported within the body of the loop.