[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
scratch/handler-bind-2 9f8ea786918 07/16: eval.c: Add new var `lisp-eval
From: |
Stefan Monnier |
Subject: |
scratch/handler-bind-2 9f8ea786918 07/16: eval.c: Add new var `lisp-eval-depth-reserve` |
Date: |
Wed, 27 Dec 2023 23:53:30 -0500 (EST) |
branch: scratch/handler-bind-2
commit 9f8ea786918a03057802a6959cbbe41b5ed0feaa
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
eval.c: Add new var `lisp-eval-depth-reserve`
Rather than blindly increase `max-lisp-eval-depth` when entering the
debugger or running `signal-hook-function`, use this new "reserve"
to keep track of how much we have grown the stack for "debugger"
purposes so that for example recursive calls to `signal-hook-function`
can't eat up the whole C stack.
* src/eval.c (max_ensure_room): Rewrite.
(restore_stack_limits): Move before `max_ensure_room`. Rewrite.
(call_debugger, signal_or_quit): Adjust calls accordingly.
Also grow `max-lisp-eval-depth` for `hander-bind` handlers.
(init_eval_once): Don't initialize `max_lisp_eval_depth` here.
(syms_of_eval): Initialize it here instead.
Add new var `lisp-eval-depth-reserve`.
---
src/eval.c | 55 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 32 insertions(+), 23 deletions(-)
diff --git a/src/eval.c b/src/eval.c
index b2b110da15b..67cd6efe6eb 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -212,7 +212,6 @@ void
init_eval_once (void)
{
/* Don't forget to update docs (lispref node "Eval"). */
- max_lisp_eval_depth = 1600;
Vrun_hooks = Qnil;
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
}
@@ -248,22 +247,29 @@ init_eval (void)
redisplay_deep_handler = NULL;
}
-/* Ensure that *M is at least A + B if possible, or is its maximum
- value otherwise. */
-
static void
-max_ensure_room (intmax_t *m, intmax_t a, intmax_t b)
+restore_stack_limits (Lisp_Object data)
{
- intmax_t sum = ckd_add (&sum, a, b) ? INTMAX_MAX : sum;
- *m = max (*m, sum);
+ intmax_t old_depth;
+ integer_to_intmax (data, &old_depth);
+ lisp_eval_depth_reserve += max_lisp_eval_depth - old_depth;
+ max_lisp_eval_depth = old_depth;
}
-/* Unwind-protect function used by call_debugger. */
+/* Try and ensure that we have at least B dpeth available. */
static void
-restore_stack_limits (Lisp_Object data)
+max_ensure_room (intmax_t b)
{
- integer_to_intmax (data, &max_lisp_eval_depth);
+ intmax_t sum = ckd_add (&sum, lisp_eval_depth, b) ? INTMAX_MAX : sum;
+ intmax_t diff = min (sum - max_lisp_eval_depth, lisp_eval_depth_reserve);
+ if (diff <= 0)
+ return;
+ intmax_t old_depth = max_lisp_eval_depth;
+ max_lisp_eval_depth += diff;
+ lisp_eval_depth_reserve -= diff;
+ /* Restore limits after leaving the debugger. */
+ record_unwind_protect (restore_stack_limits, make_int (old_depth));
}
/* Call the Lisp debugger, giving it argument ARG. */
@@ -274,16 +280,12 @@ call_debugger (Lisp_Object arg)
bool debug_while_redisplaying;
specpdl_ref count = SPECPDL_INDEX ();
Lisp_Object val;
- intmax_t old_depth = max_lisp_eval_depth;
/* The previous value of 40 is too small now that the debugger
prints using cl-prin1 instead of prin1. Printing lists nested 8
deep (which is the value of print-level used in the debugger)
currently requires 77 additional frames. See bug#31919. */
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
-
- /* Restore limits after leaving the debugger. */
- record_unwind_protect (restore_stack_limits, make_int (old_depth));
+ max_ensure_room (100);
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
@@ -1802,16 +1804,13 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object
data, bool keyboard_quit)
/* This hook is used by edebug. */
if (! NILP (Vsignal_hook_function)
- && ! NILP (error_symbol)
- /* Don't try to call a lisp function if we've already overflowed
- the specpdl stack. */
- && specpdl_ptr < specpdl_end)
+ && ! NILP (error_symbol))
{
- /* Edebug takes care of restoring these variables when it exits. */
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
-
+ specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (20);
/* FIXME: 'handler-bind' makes `signal-hook-function' obsolete? */
call2 (Vsignal_hook_function, error_symbol, data);
+ unbind_to (count, Qnil);
}
conditions = Fget (real_error_symbol, Qerror_conditions);
@@ -1849,9 +1848,12 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object
data, bool keyboard_quit)
Lisp_Object error_data
= (NILP (error_symbol)
? data : Fcons (error_symbol, data));
+ specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (20);
push_handler (make_fixnum (skip + h->bytecode_dest),
SKIP_CONDITIONS);
call1 (h->val, error_data);
+ unbind_to (count, Qnil);
pop_handler ();
}
continue;
@@ -1901,8 +1903,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object
data, bool keyboard_quit)
&& NILP (Vinhibit_debugger)
&& !NILP (Ffboundp (Qdebug_early)))
{
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (100);
AUTO_STRING (redisplay_trace, "*Redisplay-trace*");
Lisp_Object redisplay_trace_buffer;
AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace*
*/
@@ -4345,6 +4347,13 @@ actual stack overflow in C, which would be fatal for
Emacs.
You can safely make it considerably larger than its default value,
if that proves inconveniently small. However, if you increase it too far,
Emacs could overflow the real C stack, and crash. */);
+ max_lisp_eval_depth = 1600;
+
+ DEFVAR_INT ("lisp-eval-depth-reserve", lisp_eval_depth_reserve,
+ doc: /* Extra depth that can be allocated to handle errors.
+This is the max depth that the system will add to `max-lisp-eval-depth'
+when calling debuggers or `handler-bind' handlers. */);
+ lisp_eval_depth_reserve = 200;
DEFVAR_LISP ("quit-flag", Vquit_flag,
doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is
non-nil.
- branch scratch/handler-bind-2 created (now 94b11fc0c9b), Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 a4efbe4c499 01/16: New special form `handler-bind`, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 9f8ea786918 07/16: eval.c: Add new var `lisp-eval-depth-reserve`,
Stefan Monnier <=
- scratch/handler-bind-2 40437afc8ee 09/16: (signal_or_quit): Preserve error object identity, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 19f1d2a9f51 02/16: (eval-expression): Fix bug#67196, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 10e04044c7b 06/16: (macroexp--with-extended-form-stack): Use plain `let`, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 617d568f4b6 03/16: ert.el: Use `handler-bind` to record backtraces, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 b21a22c86cc 13/16: Allow the `error-message` property to be a function, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 5a3ed126ccc 14/16: tramp.el: Use `handler-bind` instead of `signal-hook-function`, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 c03598f1323 11/16: src/eval.c (call_debugger): Don't bind `Qinhibit_changing_match_data`, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 bb9e093a106 08/16: Use handler-bind to repair bytecomp-tests, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 bc5500be3b0 15/16: (edebug-format): Make it obsolete, Stefan Monnier, 2023/12/27
- scratch/handler-bind-2 d9f047e2da5 05/16: Move batch backtrace code to `top_level_2`, Stefan Monnier, 2023/12/27