Skip to content

Skip fetching the thread state for non-GC-tracked objects in _Py_Dealloc #154429

Closed as duplicate

Description

@johng

Feature or enhancement

Proposal:

_Py_Dealloc() unconditionally fetches the current thread state and computes the C recursion margin on every deallocation:

PyThreadState *tstate = _PyThreadState_GET();
intptr_t margin = _Py_RecursionLimit_GetMargin(tstate);
if (margin < 2 && gc_flag) { /* trashcan deposit */ }

Both values are only consumed by the trashcan mechanism, which applies exclusively to GC-tracked types — only they can form the deep deallocation chains the trashcan guards against. For the common non-GC case (int, float, str and other atomic types), fetching the thread state and computing the margin is wasted work.

On most platforms _PyThreadState_GET() is a cheap thread-local load, but on macOS a _Thread_local access compiles to a function call to the TLV resolver (tlv_get_addr), so this is a real per-deallocation cost on Apple Silicon. Deallocation of non-GC atomic temporaries is one of the most frequent operations in typical workloads.

Gating the thread-state fetch and margin computation behind gc_flag skips them entirely for non-GC objects. The change is small and semantics-preserving.

Preliminary microbenchmark results (compute/allocation-heavy microbenchmarks, non-PGO build): ~1% faster on an Apple Silicon free-threaded build; neutral on Linux/x86-64 (where the thread-local read is already a fixed-offset load, so there is nothing to skip). Broader benchmarking (pyperformance, PGO/LTO) is still to be done.

Has this already been discussed elsewhere?

This is a minor feature or performance improvement

Linked PRs

Activity

  1. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    pendingThe issue will be closed if no feedback is provided
    on Jul 22, 2026
  2. sergey-miryanov commented on Jul 22, 2026

    @sergey-miryanov
    Contributor

    Duplicate of #154401

  3. removed
    pendingThe issue will be closed if no feedback is provided
    on Jul 22, 2026
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)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions