diff options
| author | Matt Armstrong | 2022-10-19 13:42:35 -0700 |
|---|---|---|
| committer | Stefan Monnier | 2022-10-19 21:35:09 -0400 |
| commit | 06252617b2c4cc9bcdd9407f1e709a7e0908cf27 (patch) | |
| tree | 494a0f21b5f87949886c57bfba87bd4ab013f49b /src/alloc.c | |
| parent | 8159d8b1a71dd59e31060f00b2abe20ad9d1f924 (diff) | |
| download | emacs-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/alloc.c')
| -rw-r--r-- | src/alloc.c | 22 |
1 files changed, 19 insertions, 3 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 | |||
| 6520 | static void | ||
| 6521 | mark_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 | ||
| 6515 | static void | 6532 | static 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 && |