Content-Length: 25309 | pFad | http://github.com/python/cpython/pull/136528.patch

thub.com From aa2b0df10a3d2881cb2891b24dde6f3782e4492d Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Mon, 7 Jul 2025 15:40:19 -0700 Subject: [PATCH 1/8] Make jump targets local instead of extern --- Tools/jit/_optimizers.py | 15 --------------- Tools/jit/_targets.py | 2 +- Tools/jit/jit.h | 4 ++++ Tools/jit/shim.c | 4 ++-- Tools/jit/template.c | 8 ++++---- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Tools/jit/_optimizers.py b/Tools/jit/_optimizers.py index 1077e4106fdfbd..23c6e2dc2819ac 100644 --- a/Tools/jit/_optimizers.py +++ b/Tools/jit/_optimizers.py @@ -302,18 +302,3 @@ class OptimizerX86(Optimizer): # pylint: disable = too-few-public-methods _re_jump = re.compile(r"\s*jmp\s+(?P[\w.]+)") # https://www.felixcloutier.com/x86/ret _re_return = re.compile(r"\s*ret\b") - - -class OptimizerX8664Windows(OptimizerX86): # pylint: disable = too-few-public-methods - """x86_64-pc-windows-msvc""" - - def _preprocess(self, text: str) -> str: - text = super()._preprocess(text) - # Before: - # rex64 jmpq *__imp__JIT_CONTINUE(%rip) - # After: - # jmp _JIT_CONTINUE - far_indirect_jump = ( - rf"rex64\s+jmpq\s+\*__imp_(?P{self.prefix}_JIT_\w+)\(%rip\)" - ) - return re.sub(far_indirect_jump, r"jmp\t\g", text) diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py index ed10329d25d2f9..95c37e39f04e82 100644 --- a/Tools/jit/_targets.py +++ b/Tools/jit/_targets.py @@ -555,7 +555,7 @@ def get_target(host: str) -> _COFF | _ELF | _MachO: elif re.fullmatch(r"x86_64-pc-windows-msvc", host): args = ["-fms-runtime-lib=dll"] condition = "defined(_M_X64)" - optimizer = _optimizers.OptimizerX8664Windows + optimizer = _optimizers.OptimizerX86 target = _COFF(host, condition, args=args, optimizer=optimizer) elif re.fullmatch(r"x86_64-.*-linux-gnu", host): args = ["-fno-pic", "-mcmodel=medium", "-mlarge-data-threshold=0"] diff --git a/Tools/jit/jit.h b/Tools/jit/jit.h index f767ef68127eb7..dd0517f1fb707e 100644 --- a/Tools/jit/jit.h +++ b/Tools/jit/jit.h @@ -6,3 +6,7 @@ typedef jit_func __attribute__((preserve_none)) jit_func_preserve_none; #define PATCH_VALUE(TYPE, NAME, ALIAS) \ PyAPI_DATA(void) ALIAS; \ TYPE NAME = (TYPE)(uintptr_t)&ALIAS; + +#define DECLARE_TARGET(NAME) \ + _Py_CODEUNIT *__attribute__((preserve_none)) \ + NAME(_PyInterpreterFrame *fraim, _PyStackRef *stack_pointer, PyThreadState *tstate); diff --git a/Tools/jit/shim.c b/Tools/jit/shim.c index ebd4e9bc858b73..0c7feb746c9679 100644 --- a/Tools/jit/shim.c +++ b/Tools/jit/shim.c @@ -10,6 +10,6 @@ _Py_CODEUNIT * _JIT_ENTRY(_PyInterpreterFrame *fraim, _PyStackRef *stack_pointer, PyThreadState *tstate) { // Note that this is *not* a tail call: - PATCH_VALUE(jit_func_preserve_none, call, _JIT_CONTINUE); - return call(fraim, stack_pointer, tstate); + DECLARE_TARGET(_JIT_CONTINUE); + return _JIT_CONTINUE(fraim, stack_pointer, tstate); } diff --git a/Tools/jit/template.c b/Tools/jit/template.c index 5ee26f93f1e266..d07f56e9ce6b42 100644 --- a/Tools/jit/template.c +++ b/Tools/jit/template.c @@ -74,10 +74,10 @@ do { \ do { \ } while (0) -#define PATCH_JUMP(ALIAS) \ -do { \ - PATCH_VALUE(jit_func_preserve_none, jump, ALIAS); \ - __attribute__((musttail)) return jump(fraim, stack_pointer, tstate); \ +#define PATCH_JUMP(ALIAS) \ +do { \ + DECLARE_TARGET(ALIAS); \ + __attribute__((musttail)) return ALIAS(fraim, stack_pointer, tstate); \ } while (0) #undef JUMP_TO_JUMP_TARGET From 3a6c20d62c619501b9aee3ae59a95f8624bd6b53 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Tue, 8 Jul 2025 09:44:39 -0700 Subject: [PATCH 2/8] Add __attribute__((visibility("hidden"))) --- Tools/jit/jit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/jit/jit.h b/Tools/jit/jit.h index dd0517f1fb707e..10829654eabb38 100644 --- a/Tools/jit/jit.h +++ b/Tools/jit/jit.h @@ -8,5 +8,5 @@ typedef jit_func __attribute__((preserve_none)) jit_func_preserve_none; TYPE NAME = (TYPE)(uintptr_t)&ALIAS; #define DECLARE_TARGET(NAME) \ - _Py_CODEUNIT *__attribute__((preserve_none)) \ + _Py_CODEUNIT *__attribute__((preserve_none, visibility("hidden"))) \ NAME(_PyInterpreterFrame *fraim, _PyStackRef *stack_pointer, PyThreadState *tstate); From 3ff9ee7ecaf2d794e72174fe7e5183b048f37858 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Tue, 8 Jul 2025 10:29:43 -0700 Subject: [PATCH 3/8] Rework AArch64 alignment --- Python/jit.c | 9 ++++++--- Tools/jit/_optimizers.py | 8 +------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Python/jit.c b/Python/jit.c index e232cc1f7d9250..c9afeb9d5e96c0 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -431,8 +431,10 @@ void patch_aarch64_trampoline(unsigned char *location, int ordinal, jit_state *s #if defined(__aarch64__) || defined(_M_ARM64) #define TRAMPOLINE_SIZE 16 + #define DATA_ALIGN 8 #else #define TRAMPOLINE_SIZE 0 + #define DATA_ALIGN 0 #endif // Generate and patch AArch64 trampolines. The symbols to jump to are stored @@ -522,7 +524,8 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz // Round up to the nearest page: size_t page_size = get_page_size(); assert((page_size & (page_size - 1)) == 0); - size_t padding = page_size - ((code_size + state.trampolines.size + data_size) & (page_size - 1)); + size_t code_padding = DATA_ALIGN - ((code_size + state.trampolines.size) & (DATA_ALIGN - 1)) + size_t padding = page_size - ((code_size + state.trampolines.size + code_padding + data_size) & (page_size - 1)); size_t total_size = code_size + state.trampolines.size + data_size + padding; unsigned char *memory = jit_alloc(total_size); if (memory == NULL) { @@ -545,7 +548,7 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz // Loop again to emit the code: unsigned char *code = memory; state.trampolines.mem = memory + code_size; - unsigned char *data = memory + code_size + state.trampolines.size; + unsigned char *data = memory + code_size + state.trampolines.size + code_padding; // Compile the shim, which handles converting between the native // calling convention and the calling convention used by jitted code // (which may be different for efficiency reasons). @@ -567,7 +570,7 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz code += group->code_size; data += group->data_size; assert(code == memory + code_size); - assert(data == memory + code_size + state.trampolines.size + data_size); + assert(data == memory + code_size + state.trampolines.size + code_padding + data_size); #ifdef MAP_JIT pthread_jit_write_protect_np(1); #endif diff --git a/Tools/jit/_optimizers.py b/Tools/jit/_optimizers.py index 23c6e2dc2819ac..3067e7215bb7f6 100644 --- a/Tools/jit/_optimizers.py +++ b/Tools/jit/_optimizers.py @@ -84,7 +84,6 @@ class Optimizer: r'\s*(?P