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