Skip to content

Use deferred reference counting in some _PyInterpreterFrame fields #123923

@colesbury

Description

@colesbury

Feature or enhancement

The _PyInterpreterFrame struct contains a strong reference to:

  • f_executable - the currently executing code object
  • f_funcobj - the function object
  • f_locals - the locals object (often NULL)
  • frame_obj - the frame object (often NULL)

We should use deferred references (in the free-threaded build) for f_executable and f_funcobj because they are a common source of reference count contention. The pointed to objects (code and function) already support deferred reference counting, but the references in the frame are not deferred.

I think we don't need to bother with changing f_locals for now. I don't think it's used frequently enough to be a bottleneck, but we can revisit it later if necessary.

The frame_obj are typically unique -- not shared across threads -- so we don't need to bother with deferred reference counting for frame_obj.

Complications and hazards

_PyInterpreterFrame are also embedded in generators/coroutines and PyFrameObject, which are heap objects. We need to be careful that _PyStackRef fields are visible to the GC in order to be kept alive. Once an object is untracked, the _PyStackRef fields may no longer be valid: it's safe to call PyStackRef_CLOSE/CLEAR but not otherwise access or dereference those fields because the GC may have already collected them.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions