Skip to content

Commit d77cf29

Browse files
committed
Address feedback
1 parent 460d0d3 commit d77cf29

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

Tools/jit/_stencils.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,22 @@ def pad(self, alignment: int) -> None:
209209
self.disassembly.append(f"{offset:x}: {' '.join(['00'] * padding)}")
210210
self.body.extend([0] * padding)
211211

212-
def add_nop(self, alignment: int) -> None:
213-
"""Add a NOP if the offset is not aligned."""
212+
def add_nops(self, nop: bytes, alignment: int) -> None:
213+
"""Add NOPs until there is alignment. Fail if it is not possible."""
214214
offset = len(self.body)
215-
nop = b"\x1f\x20\x03\xD5"
216-
if offset % alignment:
217-
self.disassembly.append(f"{offset:x}: d503201f\t\t nop")
218-
self.body.extend(nop)
215+
nop_size = len(nop)
216+
217+
# Calculate the gap to the next multiple of alignment.
218+
gap = -offset % alignment
219+
if gap:
220+
if gap % nop_size == 0:
221+
count = gap // nop_size
222+
self.body.extend(nop * count)
223+
else:
224+
raise ValueError(
225+
f"Cannot add nops of size '{nop_size}' to a body with "
226+
f"offset '{offset}' to align with '{alignment}'"
227+
)
219228

220229
def remove_jump(self) -> None:
221230
"""Remove a zero-length continuation jump, if it exists."""
@@ -254,7 +263,6 @@ def remove_jump(self) -> None:
254263
return
255264
if self.body[offset:] == jump:
256265
self.body = self.body[:offset]
257-
self.disassembly = self.disassembly[:-2]
258266
self.holes.remove(hole)
259267

260268

@@ -275,10 +283,7 @@ class StencilGroup:
275283
_trampolines: set[int] = dataclasses.field(default_factory=set, init=False)
276284

277285
def process_relocations(
278-
self,
279-
known_symbols: dict[str, int],
280-
*,
281-
alignment: int = 1,
286+
self, known_symbols: dict[str, int], *, alignment: int = 1, nop: bytes = b""
282287
) -> None:
283288
"""Fix up all GOT and internal relocations for this stencil group."""
284289
for hole in self.code.holes.copy():
@@ -299,7 +304,7 @@ def process_relocations(
299304
hole.addend = ordinal
300305
hole.symbol = None
301306
self.code.remove_jump()
302-
self.code.add_nop(alignment=alignment)
307+
self.code.add_nops(nop=nop, alignment=alignment)
303308
self.data.pad(8)
304309
for stencil in [self.code, self.data]:
305310
for hole in stencil.holes:

Tools/jit/_targets.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ class _Target(typing.Generic[_S, _R]):
4444
verbose: bool = False
4545
known_symbols: dict[str, int] = dataclasses.field(default_factory=dict)
4646

47+
def _get_nop(self) -> bytes:
48+
if re.fullmatch(r"aarch64-.*", self.triple):
49+
nop = b"\x1f\x20\x03\xD5"
50+
elif re.fullmatch(r"x86_64-.*|i686.*", self.triple):
51+
nop = b"\x90"
52+
else:
53+
raise ValueError(f"NOP not defined for {self.triple}")
54+
return nop
55+
4756
def _compute_digest(self, out: pathlib.Path) -> str:
4857
hasher = hashlib.sha256()
4958
hasher.update(self.triple.encode())
@@ -172,7 +181,9 @@ async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:
172181
stencil_groups = {task.get_name(): task.result() for task in tasks}
173182
for stencil_group in stencil_groups.values():
174183
stencil_group.process_relocations(
175-
known_symbols=self.known_symbols, alignment=self.alignment
184+
known_symbols=self.known_symbols,
185+
alignment=self.alignment,
186+
nop=self._get_nop(),
176187
)
177188
return stencil_groups
178189

0 commit comments

Comments
 (0)