diff options
| author | Mattias EngdegÄrd | 2022-02-16 16:52:07 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2022-03-12 17:32:31 +0100 |
| commit | 213483124b4381663efd0dd001037363223ce188 (patch) | |
| tree | f7b355d3c0c56d6cd417e043a842e2ae91c8f113 | |
| parent | 6ef9dc7797729a547dace431f57a73fe278172cc (diff) | |
| download | emacs-213483124b4381663efd0dd001037363223ce188.tar.gz emacs-213483124b4381663efd0dd001037363223ce188.zip | |
Inline record_in_backtrace
It's critical in several function call paths.
* src/eval.c (grow_specpdl_allocation): Make non-static.
(grow_specpdl, record_in_backtrace): Move from here...
* src/lisp.h (grow_specpdl, record_in_backtrace): ... to here,
and declare inline.
| -rw-r--r-- | src/eval.c | 36 | ||||
| -rw-r--r-- | src/lisp.h | 35 |
2 files changed, 36 insertions, 35 deletions
diff --git a/src/eval.c b/src/eval.c index 294d79e67a0..0fc492fbe0e 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2320,7 +2320,7 @@ alist mapping symbols to their value. */) | |||
| 2320 | return unbind_to (count, eval_sub (form)); | 2320 | return unbind_to (count, eval_sub (form)); |
| 2321 | } | 2321 | } |
| 2322 | 2322 | ||
| 2323 | static void | 2323 | void |
| 2324 | grow_specpdl_allocation (void) | 2324 | grow_specpdl_allocation (void) |
| 2325 | { | 2325 | { |
| 2326 | eassert (specpdl_ptr == specpdl + specpdl_size); | 2326 | eassert (specpdl_ptr == specpdl + specpdl_size); |
| @@ -2342,40 +2342,6 @@ grow_specpdl_allocation (void) | |||
| 2342 | specpdl_ptr = specpdl_ref_to_ptr (count); | 2342 | specpdl_ptr = specpdl_ref_to_ptr (count); |
| 2343 | } | 2343 | } |
| 2344 | 2344 | ||
| 2345 | /* Grow the specpdl stack by one entry. | ||
| 2346 | The caller should have already initialized the entry. | ||
| 2347 | Signal an error on stack overflow. | ||
| 2348 | |||
| 2349 | Make sure that there is always one unused entry past the top of the | ||
| 2350 | stack, so that the just-initialized entry is safely unwound if | ||
| 2351 | memory exhausted and an error is signaled here. Also, allocate a | ||
| 2352 | never-used entry just before the bottom of the stack; sometimes its | ||
| 2353 | address is taken. */ | ||
| 2354 | |||
| 2355 | INLINE void | ||
| 2356 | grow_specpdl (void) | ||
| 2357 | { | ||
| 2358 | specpdl_ptr++; | ||
| 2359 | if (specpdl_ptr == specpdl + specpdl_size) | ||
| 2360 | grow_specpdl_allocation (); | ||
| 2361 | } | ||
| 2362 | |||
| 2363 | specpdl_ref | ||
| 2364 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | ||
| 2365 | { | ||
| 2366 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 2367 | |||
| 2368 | eassert (nargs >= UNEVALLED); | ||
| 2369 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; | ||
| 2370 | specpdl_ptr->bt.debug_on_exit = false; | ||
| 2371 | specpdl_ptr->bt.function = function; | ||
| 2372 | current_thread->stack_top = specpdl_ptr->bt.args = args; | ||
| 2373 | specpdl_ptr->bt.nargs = nargs; | ||
| 2374 | grow_specpdl (); | ||
| 2375 | |||
| 2376 | return count; | ||
| 2377 | } | ||
| 2378 | |||
| 2379 | /* Eval a sub-expression of the current expression (i.e. in the same | 2345 | /* Eval a sub-expression of the current expression (i.e. in the same |
| 2380 | lexical scope). */ | 2346 | lexical scope). */ |
| 2381 | Lisp_Object | 2347 | Lisp_Object |
diff --git a/src/lisp.h b/src/lisp.h index 778bd1bfa5a..b99441fa6c1 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3454,6 +3454,41 @@ backtrace_debug_on_exit (union specbinding *pdl) | |||
| 3454 | return pdl->bt.debug_on_exit; | 3454 | return pdl->bt.debug_on_exit; |
| 3455 | } | 3455 | } |
| 3456 | 3456 | ||
| 3457 | void grow_specpdl_allocation (void); | ||
| 3458 | |||
| 3459 | /* Grow the specpdl stack by one entry. | ||
| 3460 | The caller should have already initialized the entry. | ||
| 3461 | Signal an error on stack overflow. | ||
| 3462 | |||
| 3463 | Make sure that there is always one unused entry past the top of the | ||
| 3464 | stack, so that the just-initialized entry is safely unwound if | ||
| 3465 | memory exhausted and an error is signaled here. Also, allocate a | ||
| 3466 | never-used entry just before the bottom of the stack; sometimes its | ||
| 3467 | address is taken. */ | ||
| 3468 | INLINE void | ||
| 3469 | grow_specpdl (void) | ||
| 3470 | { | ||
| 3471 | specpdl_ptr++; | ||
| 3472 | if (specpdl_ptr == specpdl + specpdl_size) | ||
| 3473 | grow_specpdl_allocation (); | ||
| 3474 | } | ||
| 3475 | |||
| 3476 | INLINE specpdl_ref | ||
| 3477 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | ||
| 3478 | { | ||
| 3479 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 3480 | |||
| 3481 | eassert (nargs >= UNEVALLED); | ||
| 3482 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; | ||
| 3483 | specpdl_ptr->bt.debug_on_exit = false; | ||
| 3484 | specpdl_ptr->bt.function = function; | ||
| 3485 | current_thread->stack_top = specpdl_ptr->bt.args = args; | ||
| 3486 | specpdl_ptr->bt.nargs = nargs; | ||
| 3487 | grow_specpdl (); | ||
| 3488 | |||
| 3489 | return count; | ||
| 3490 | } | ||
| 3491 | |||
| 3457 | /* This structure helps implement the `catch/throw' and `condition-case/signal' | 3492 | /* This structure helps implement the `catch/throw' and `condition-case/signal' |
| 3458 | control structures. A struct handler contains all the information needed to | 3493 | control structures. A struct handler contains all the information needed to |
| 3459 | restore the state of the interpreter after a non-local jump. | 3494 | restore the state of the interpreter after a non-local jump. |