GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Refactor perf trampoline proposal: split the assembly per architecture, auto-generate DWARF unwind data · Issue #149800 · python/cpython

Refactor perf trampoline proposal: split the assembly per architecture, auto-generate DWARF unwind data #149800

New issue
Copy link
New issue
Copy link
Open
#157246
Open
Refactor perf trampoline proposal: split the assembly per architecture, auto-generate DWARF unwind data#149800
#157246
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

Description

@stratakis
stratakis
opened on May 13, 2026
Issue body actions

Feature or enhancement

Proposal:

Not a user visible feature per se but I still think it warrants discussion.

The problem:

I've been working on fixing up the RISC-V support for perf and also checking out adding s390x and ppc64le but the process is quite tedious, I'd say and the various connections around this infra are fragile, so I've been thinking of how to make the process a little bit easier and more maintainable/readable.

The steps to add perf trampoline support for a new CPU architecture currently:

  • Arch-specific assembly in Python/asm_trampoline.S (new #ifdef blocks for each arch)
  • DWARF register number enums, CIE parameters and FDE body. Python/jit_unwind.c
  • ELF machine constants in Python/perf_jit_trampoline.c
  • platform triplets in configure.

The DWARF CFI instructions must mirror the assembly. This synchronization needs to be done manually and involves compiling a C equivalent of the trampoline, running readelf, and hand-translating the output into DWRF macros. Getting it wrong can produces silent failures, broken stack unwinding.

With x86-64, aarch64, and RISC-V there (RISC-V broken atm), when adding more things there, the assembly file is becoming bigger and less readable, elf_init_ehframe_perf() is becoming a wall of #ifdef blocks without much shared logic and so on.

Proposal1:

Split assembly files.

Replace the single Python/asm_trampoline.S with per-arch files:

  • Python/asm_trampoline_x86_64.S
  • Python/asm_trampoline_aarch64.S
  • Python/asm_trampoline_riscv64.S
  • (maybe in the future: asm_trampoline_ppc64le.S, asm_trampoline_s390x.S)

configure.ac is modified accordingly and selects which file to compile depending on arch. With each file self-contained, each arch can be reviewed, modified, tested independently. This will also require a few more lines in configure and careful handling of the MacOS case.

Proposal2 (followup):

Auto-generate DWARF data from compiled assembly.

A build-time script extracts the .eh_frame section from the compiled trampoline object and generates a header with the raw DWARF unwind data. At runtime, elf_init_ehframe_perf() copies this data and patches in the actual code address and size, replacing the current architecture-specific DWARF generation code entirely.

The JIT's Tools/jit/build.py already extracts DWARF CFI data from compiled objects to generate jit_unwind_info-.h for the GDB unwind path so something similar could be deployed here.

Another possibility would be a dependency on readelf, but I don't think that this is something desirable.

Pros and cons

Pros:

  • Adding a new architecture requires exactly one new file (the assembly) and a few lines in configure.ac. No DWARF knowledge needed (assuming the DWARF extraction script is robust :) ).
  • Eliminates possible bugs with syncronization of DWARF data (or move them to the extraction script, either way it should be simpler to deal with)
  • jit_unwind.c's elf_init_ehframe_perf shrinks to only the arch-independent code.

Cons

  • PYTHON_FOR_REGEN must be available when the trampoline assembly changes (same constraint as JIT stencil generation). That practically means that perf support will now depend on PYTHON_FOR_REGEN, making it unavailable for "clean" builds.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

  • gh-149800: Split perf trampoline assembly into per-architecture files #149894
  • gh-149800: Fix macOS universal2 build of perf trampoline (GH-149894 follow-up) #150364
  • gh-149800: Fix macOS universal2 build of perf trampoline #150365
  • gh-149800: Generate the perf trampoline .eh_frame from the compiled assembly #157246
Reacted by Diego Russo

Activity

  1. stratakis
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on May 13, 2026
  2. stratakis commented on May 13, 2026

    @stratakis
    stratakis
    on May 13, 2026
    ContributorAuthor
    More actions

    cc @pablogsal @diegorusso

  3. pablogsal commented on May 13, 2026

    @pablogsal
    pablogsal
    on May 13, 2026
    Member
    More actions

    I think we should do this.

    This file has evolved a lot since the original version I wrote and now we are using it also for other purposes. Also one clarification: the process you describe is what I documented so people that are not familiar with dwarf could maintain this file but the original dwarf was hand written and it didn't match what gcc or clang emitted to make it more efficient.

    But I agree that it would be ideal if we don't need to manually write any of this and we can take the eh_frame from a working compiler.

    @stratakis do you want to give this a go?

  4. picnixz
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)
    and removed
    type-featureA feature request or enhancementA feature request or enhancement
    on May 13, 2026
  5. stratakis commented on May 13, 2026

    @stratakis
    stratakis
    on May 13, 2026
    ContributorAuthor
    More actions

    Sure I'd love to try it out. Does the overall proposal sound good? Anything you'd change or point out? Ideally I'd go for splitting the trampolines first and have that in place and then work on the more complex work of extracting dwarf information.

  6. pablogsal commented on May 14, 2026

    @pablogsal
    pablogsal
    on May 14, 2026
    Member
    More actions

    The trampoline splitting is the part that I thing has the lowest impact on maintainance. I am not opposed to it so happy if you want to give it a go but I am much more enthusiastic about not having to write the DWARF by hand ;)

  7. diegorusso commented on May 14, 2026

    @diegorusso
    diegorusso
    on May 14, 2026
    Contributor
    More actions

    I totally agree with the goal of the issue as I relate with the complexity and fragility of the whole system.
    I'm also in favour of the 2 proposal (split asm files and autogenerate DWARF from them)

    The JIT's Tools/jit/build.py already extracts DWARF CFI data from compiled objects to generate jit_unwind_info-.h for the GDB unwind path so something similar could be deployed here.

    On this I've leveraged the fact that we have already a hard dependency on the llvm toolchain to extract DWARF information. Early iterations of the PR had a manual parser (written by Pablo).
    If we go towards the direction of extracting DWARF data from compiled objects, it would great to keep in mind that we could potentially have one tool that does that.

    But please, by any means, carry on with the changes and thanks for tackling this!

  8. pablogsal
    added a commit that references this issue on May 23, 2026

    gh-149800: Split perf trampoline assembly into per-architecture files (…

    b0a149a
  9. eendebakpt
    added a commit that references this issue on May 24, 2026

    pythongh-149800: Fix macOS universal2 build of perf trampoline

    1d010ee
  10. pablogsal
    added 2 commits that reference this issue on May 24, 2026

    pythongh-149800: Fix macOS universal2 build of perf trampoline (pytho…

    cf94a02

    gh-149800: Fix macOS universal2 build of perf trampoline (GH-149894 f…

    e6b17d1
  11. stratakis
    added 8 commits that reference this issue on Sep 10, 2026

    pythongh-149800: Add CFI directives to the perf trampoline assembly

    2d6a384

    pythongh-149800: Declare the perf trampoline template labels as char …

    8664afd

    pythongh-149800: Generate the perf trampoline .eh_frame from the comp…

    3d65521

    pythongh-149800: Test the generated perf trampoline unwind data

    2d6fb15

    pythongh-149800: Add CFI directives to the perf trampoline assembly

    30241aa

    pythongh-149800: Declare the perf trampoline template labels as char …

    4439b52

    pythongh-149800: Generate the perf trampoline .eh_frame from the comp…

    b63f0d1

    pythongh-149800: Test the generated perf trampoline unwind data

    5534711
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.