diff options
| author | Mattias EngdegÄrd | 2025-10-08 18:03:08 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2025-10-16 19:27:17 +0200 |
| commit | f4e3fce9ea80973269d24b7179ae2ad2cbff83d0 (patch) | |
| tree | 1a86226ad6096312e5b5daf87cb551717a1e286a | |
| parent | 8d6d4a9856f010519abeed503249e172625e9da5 (diff) | |
| download | emacs-f4e3fce9ea80973269d24b7179ae2ad2cbff83d0.tar.gz emacs-f4e3fce9ea80973269d24b7179ae2ad2cbff83d0.zip | |
exec_byte_code: use fixed registers for top and pc (bug#79610)
GCC seems to have difficulty allocating important global interpreter
variables in registers; telling it which ones to use for 'top' and 'pc'
makes a big difference and seems to ease pressure enough for it to
deal with other variables as well.
We do it for AMD64 and ARM64. Clang doesn't seem to need these directives.
It does result in -Wclobbered warnings that seem difficult to silence.
* src/bytecode.c (BC_REG_TOP, BC_REG_PC): New.
(exec_byte_code): Use them.
| -rw-r--r-- | src/bytecode.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index e116936e55d..c3fc3100e21 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -449,6 +449,20 @@ valid_sp (struct bc_thread_state *bc, Lisp_Object *sp) | |||
| 449 | return sp < (Lisp_Object *)fp && sp + 1 >= fp->saved_fp->next_stack; | 449 | return sp < (Lisp_Object *)fp && sp + 1 >= fp->saved_fp->next_stack; |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | /* GCC seems to have difficulty putting important variables in | ||
| 453 | registers, so give it some heavy-handed assistance by specifying | ||
| 454 | which ones to use. Use callee-saved registers to reduce spill/fill. */ | ||
| 455 | #if __GNUC__ && !__clang__ && defined __x86_64__ | ||
| 456 | #define BC_REG_TOP asm ("rbx") | ||
| 457 | #define BC_REG_PC asm ("r12") | ||
| 458 | #elif __GNUC__ && !__clang__ && defined __aarch64__ | ||
| 459 | #define BC_REG_TOP asm ("x19") | ||
| 460 | #define BC_REG_PC asm ("x20") | ||
| 461 | #else | ||
| 462 | #define BC_REG_TOP | ||
| 463 | #define BC_REG_PC | ||
| 464 | #endif | ||
| 465 | |||
| 452 | /* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity | 466 | /* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity |
| 453 | encoded as an integer (the one in FUN is ignored), and ARGS, of | 467 | encoded as an integer (the one in FUN is ignored), and ARGS, of |
| 454 | size NARGS, should be a vector of the actual arguments. The | 468 | size NARGS, should be a vector of the actual arguments. The |
| @@ -466,8 +480,8 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, | |||
| 466 | struct bc_thread_state *bc = ¤t_thread->bc; | 480 | struct bc_thread_state *bc = ¤t_thread->bc; |
| 467 | 481 | ||
| 468 | /* Values used for the first stack record when called from C. */ | 482 | /* Values used for the first stack record when called from C. */ |
| 469 | Lisp_Object *top = NULL; | 483 | register Lisp_Object *top BC_REG_TOP = NULL; |
| 470 | unsigned char const *pc = NULL; | 484 | register unsigned char const *pc BC_REG_PC = NULL; |
| 471 | 485 | ||
| 472 | Lisp_Object bytestr = AREF (fun, CLOSURE_CODE); | 486 | Lisp_Object bytestr = AREF (fun, CLOSURE_CODE); |
| 473 | 487 | ||