diff options
| author | Mattias EngdegÄrd | 2021-12-28 16:50:07 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2022-01-02 14:01:31 +0100 |
| commit | 43932a0d90c2e416e4e315397dd7df503b2d1fd6 (patch) | |
| tree | bf79b19f89e948e298271cb86c7f2e7903f35036 /src/bytecode.c | |
| parent | b2167d98432a78442522b7564e22f47d75a98b6f (diff) | |
| download | emacs-43932a0d90c2e416e4e315397dd7df503b2d1fd6.tar.gz emacs-43932a0d90c2e416e4e315397dd7df503b2d1fd6.zip | |
Short-circuit the recursive bytecode funcall chain
Inline parts of the code for function calls to speed up the common
case of calling lexbound byte-code. By eliminating intermediate
functions, this also reduces C stack usage a little.
* src/bytecode.c (exec_byte_code): Inline parts of Ffuncall,
funcall_lambda and fetch_and_exec_byte_code in the Bcall opcode
handler.
* src/eval.c (backtrace_debug_on_exit): Inline and move to lisp.h.
(do_debug_on_call): Make global so that it can be called from
bytecode.c.
(funcall_general): New function, essentially the meat of Ffuncall.
* src/lisp.h (backtrace_debug_on_exit): Moved here from eval.c.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index 472992be180..f8ffec0348a 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -629,7 +629,53 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 629 | } | 629 | } |
| 630 | } | 630 | } |
| 631 | #endif | 631 | #endif |
| 632 | TOP = Ffuncall (op + 1, &TOP); | 632 | maybe_quit (); |
| 633 | |||
| 634 | if (++lisp_eval_depth > max_lisp_eval_depth) | ||
| 635 | { | ||
| 636 | if (max_lisp_eval_depth < 100) | ||
| 637 | max_lisp_eval_depth = 100; | ||
| 638 | if (lisp_eval_depth > max_lisp_eval_depth) | ||
| 639 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); | ||
| 640 | } | ||
| 641 | |||
| 642 | ptrdiff_t numargs = op; | ||
| 643 | Lisp_Object fun = TOP; | ||
| 644 | Lisp_Object *args = &TOP + 1; | ||
| 645 | |||
| 646 | ptrdiff_t count1 = record_in_backtrace (fun, args, numargs); | ||
| 647 | maybe_gc (); | ||
| 648 | if (debug_on_next_call) | ||
| 649 | do_debug_on_call (Qlambda, count1); | ||
| 650 | |||
| 651 | Lisp_Object original_fun = fun; | ||
| 652 | if (SYMBOLP (fun)) | ||
| 653 | fun = XSYMBOL (fun)->u.s.function; | ||
| 654 | Lisp_Object template; | ||
| 655 | Lisp_Object bytecode; | ||
| 656 | Lisp_Object val; | ||
| 657 | if (COMPILEDP (fun) | ||
| 658 | // Lexical binding only. | ||
| 659 | && (template = AREF (fun, COMPILED_ARGLIST), | ||
| 660 | FIXNUMP (template)) | ||
| 661 | // No autoloads. | ||
| 662 | && (bytecode = AREF (fun, COMPILED_BYTECODE), | ||
| 663 | !CONSP (bytecode))) | ||
| 664 | val = exec_byte_code (bytecode, | ||
| 665 | AREF (fun, COMPILED_CONSTANTS), | ||
| 666 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 667 | template, numargs, args); | ||
| 668 | else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun)) | ||
| 669 | val = funcall_subr (XSUBR (fun), numargs, args); | ||
| 670 | else | ||
| 671 | val = funcall_general (original_fun, numargs, args); | ||
| 672 | |||
| 673 | lisp_eval_depth--; | ||
| 674 | if (backtrace_debug_on_exit (specpdl + count1)) | ||
| 675 | val = call_debugger (list2 (Qexit, val)); | ||
| 676 | specpdl_ptr--; | ||
| 677 | |||
| 678 | TOP = val; | ||
| 633 | NEXT; | 679 | NEXT; |
| 634 | } | 680 | } |
| 635 | 681 | ||