Skip to content

Commit a0dce37

Browse files
authored
pythonGH-119726: Deduplicate JIT trampolines for out-of-range jumps (pythonGH-120250)
1 parent 07daaf1 commit a0dce37

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
JIT: Re-use trampolines on AArch64 when creating stencils. Patch by Diego Russo

Tools/jit/_stencils.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class Stencil:
181181
body: bytearray = dataclasses.field(default_factory=bytearray, init=False)
182182
holes: list[Hole] = dataclasses.field(default_factory=list, init=False)
183183
disassembly: list[str] = dataclasses.field(default_factory=list, init=False)
184+
trampolines: dict[str, int] = dataclasses.field(default_factory=dict, init=False)
184185

185186
def pad(self, alignment: int) -> None:
186187
"""Pad the stencil to the given alignment."""
@@ -189,14 +190,25 @@ def pad(self, alignment: int) -> None:
189190
self.disassembly.append(f"{offset:x}: {' '.join(['00'] * padding)}")
190191
self.body.extend([0] * padding)
191192

192-
def emit_aarch64_trampoline(self, hole: Hole) -> None:
193+
def emit_aarch64_trampoline(self, hole: Hole, alignment: int) -> None:
193194
"""Even with the large code model, AArch64 Linux insists on 28-bit jumps."""
194-
base = len(self.body)
195+
assert hole.symbol is not None
196+
reuse_trampoline = hole.symbol in self.trampolines
197+
if reuse_trampoline:
198+
# Re-use the base address of the previously created trampoline
199+
base = self.trampolines[hole.symbol]
200+
else:
201+
self.pad(alignment)
202+
base = len(self.body)
195203
where = slice(hole.offset, hole.offset + 4)
196204
instruction = int.from_bytes(self.body[where], sys.byteorder)
197205
instruction &= 0xFC000000
198206
instruction |= ((base - hole.offset) >> 2) & 0x03FFFFFF
199207
self.body[where] = instruction.to_bytes(4, sys.byteorder)
208+
209+
if reuse_trampoline:
210+
return
211+
200212
self.disassembly += [
201213
f"{base + 4 * 0:x}: d2800008 mov x8, #0x0",
202214
f"{base + 4 * 0:016x}: R_AARCH64_MOVW_UABS_G0_NC {hole.symbol}",
@@ -225,6 +237,7 @@ def emit_aarch64_trampoline(self, hole: Hole) -> None:
225237
]
226238
):
227239
self.holes.append(hole.replace(offset=base + 4 * i, kind=kind))
240+
self.trampolines[hole.symbol] = base
228241

229242
def remove_jump(self, *, alignment: int = 1) -> None:
230243
"""Remove a zero-length continuation jump, if it exists."""
@@ -300,8 +313,7 @@ def process_relocations(self, *, alignment: int = 1) -> None:
300313
in {"R_AARCH64_CALL26", "R_AARCH64_JUMP26", "ARM64_RELOC_BRANCH26"}
301314
and hole.value is HoleValue.ZERO
302315
):
303-
self.code.pad(alignment)
304-
self.code.emit_aarch64_trampoline(hole)
316+
self.code.emit_aarch64_trampoline(hole, alignment)
305317
self.code.holes.remove(hole)
306318
self.code.remove_jump(alignment=alignment)
307319
self.code.pad(alignment)

0 commit comments

Comments
 (0)