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 — gh-117139: Convert the evaluation stack to stack refs by Fidget-Spinner · Pull Request #118450 · python/cpython

Conversation

@Fidget-Spinner

@Fidget-Spinner Fidget-Spinner commented Apr 30, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

This PR sets up tagged pointers for CPython.

The general idea is to create a separate struct _PyStackRef for everything on the evaluation stack to store the bits. This forces the C compiler to warn us if we try to cast things or pull things out of the struct directly.

Only for free threading: We tag the low bit if something is deferred - that means we skip incref and decref operations on it. This behavior may change in the future if Mark's plans to defer all objects in the interpreter loop pans out.

This implies a strict stack reference discipline is required. ALL incref and decref operations on stackrefs must use the stackref variants. It is unsafe to untag something then do normal incref/decref ops on it.

The new incref and decref variants are called dup and close. They mimic a "handle" API operating on these stackrefs.

Please read Include/internal/pycore_stackref.h for more information!

  • Issue: Set up tagged pointers in the evaluation stack #117139

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Fidget-Spinner added 6 commits May 1, 2024 04:54
@Fidget-Spinner
merge from upstream
a6275f1
@Fidget-Spinner
remove test tags
7e7627f
@Fidget-Spinner
add test for immortal
00dde8e
@Fidget-Spinner
Merge remote-tracking branch 'upstream/main' into stackref_all
eadc4fc
@Fidget-Spinner
minor cleanups
64e2800
@Fidget-Spinner
Create 2024-05-01-05-09-16.gh-issue-117139.t41w_D.rst
bf6b7e4
@bedevere-app bedevere-app Bot mentioned this pull request Apr 30, 2024
Set up tagged pointers in the evaluation stack #117139
Closed
@Fidget-Spinner
Fidget-Spinner marked this pull request as ready for review April 30, 2024 21:09
@Fidget-Spinner
Fidget-Spinner requested review from a team, brandtbucher, brettcannon, ericsnowcurrently, gvanrossum, kumaraditya303, markshannon, methane, ncoghlan and warsaw as code owners April 30, 2024 21:09
@bedevere-app bedevere-app Bot added the awaiting core review label Apr 30, 2024
@Fidget-Spinner
Fidget-Spinner requested a review from colesbury April 30, 2024 21:10
@gvanrossum

gvanrossum commented Apr 30, 2024

Copy link
Copy Markdown
Member

Could we hold off on this until 3.14? It's only a week until feature freeze for 3.13 (at which point main becomes 3.14), and this looks like a lot of churn in a time where we all would like stability to merge things that are actually needed in 3.13.

colesbury and brandtbucher reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner

Fidget-Spinner commented Apr 30, 2024

Copy link
Copy Markdown
Member Author

Could we hold off on this until 3.14? It's only a week until feature freeze for 3.13 (at which point main becomes 3.14), and this looks like a lot of churn in a time where we all would like stability to merge things that are actually needed in 3.13.

Alright. I always forget that ten other people are rushing in things at the same time as me. I don't think this will add any value for CPython 3.13 anyways at the moment.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner
remove bad assert
865ff8d
@colesbury

colesbury commented Apr 30, 2024

Copy link
Copy Markdown
Contributor

Could we hold off on this until 3.14?

That makes sense. I'll start providing feedback and reviewing this now, but it won't be merged in 3.13.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner Fidget-Spinner added the topic-free-threading label May 1, 2024
@Fidget-Spinner
rename tagged -> stackref
b1777c4
colesbury
colesbury reviewed May 1, 2024
View reviewed changes

@colesbury colesbury left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments below, mostly minor. I'll take a closer look at bytecodes.c and the generated cases next.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/gc_free_threading.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/internal/pycore_call.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/internal/pycore_ceval.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/internal/pycore_dict.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/internal/pycore_frame.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/dictobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/frameobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/bytecodes.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/bytecodes.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/bytecodes.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Fidget-Spinner added 3 commits May 3, 2024 04:02
@Fidget-Spinner
trivial fixes first
50cfefa
@Fidget-Spinner
fix anti-patterns (use deferred everywhere)
39e9057
@Fidget-Spinner
Delete 2024-03-26-20-31-34.gh-issue-117139.eELvoZ.rst
1bb3c51
@Fidget-Spinner
Fidget-Spinner requested a review from markshannon June 26, 2024 14:32
@Fidget-Spinner

Fidget-Spinner commented Jun 26, 2024

Copy link
Copy Markdown
Member Author

I'm going to merge this in an hour. We can keep iterating on it if needed after.

ericsnowcurrently reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner
Fidget-Spinner dismissed markshannon’s stale review June 26, 2024 16:53

All addressed, or can be done in follow-up PRs.

@markshannon

markshannon commented Jun 26, 2024

Copy link
Copy Markdown
Member

It seems ASAN actually caught a real bug there, where vectorcall implicitly assumes the -1 entry of a stack is available for writing self to.

It isn't implicit it depends on the flags pass https://peps.python.org/pep-0590/. Take care to set the flags to suit your buffer size.
The buildbot run you linked to was a success. Where was the failure?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner

Fidget-Spinner commented Jun 26, 2024

Copy link
Copy Markdown
Member Author

A few comments, but nothing substantial

Yeah I recall the flag, but I just blanket put +1 extra space for everything for simplicity's sake. The failure is here https://buildbot.python.org/all/#/builders/1364/builds/143.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner

Fidget-Spinner commented Jun 26, 2024

Copy link
Copy Markdown
Member Author

Nevermind, I'll change it so it checks for the flags now. Thanks PY_VECTORCALL_ARGUMENTS_OFFSET!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fidget-Spinner added 4 commits June 27, 2024 01:42
@Fidget-Spinner
Fix bug in malloc case
ce77fe4
@Fidget-Spinner
Use immortal
193e216
@Fidget-Spinner
Remove borrowed load in counter_optimize
30f7a09
@Fidget-Spinner
silence warning
ff41e0c
colesbury
colesbury approved these changes Jun 26, 2024
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting change review labels Jun 26, 2024
@Fidget-Spinner

Fidget-Spinner commented Jun 26, 2024

Copy link
Copy Markdown
Member Author

!buildbot x86-64 MacOS Intel ASAN NoGIL PR

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot

bedevere-bot commented Jun 26, 2024

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @Fidget-Spinner for commit ff41e0c 🤖

The command will test the builders whose names match following regular expression: x86-64 MacOS Intel ASAN NoGIL PR

The builders matched are:

  • x86-64 MacOS Intel ASAN NoGIL PR
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fidget-Spinner
Fidget-Spinner merged commit 22b0de2 into python:main Jun 26, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Jun 26, 2024
@Fidget-Spinner
Fidget-Spinner deleted the stackref_all branch June 26, 2024 19:10
@Zheaoli Zheaoli mentioned this pull request Jun 27, 2024
CPython build failed with --enable-pystats after #118450 #121082
Closed
Fidget-Spinner added a commit that referenced this pull request Jun 27, 2024
@Zheaoli @Fidget-Spinner
gh-121082: Fix build failure when the developer use `--enable-pystats…
223c03a
…` arguments in configuration command after #118450 (#121083)



Signed-off-by: Manjusaka <[email protected]>
Co-authored-by: Ken Jin <[email protected]>
mrahtz pushed a commit to mrahtz/cpython that referenced this pull request Jun 30, 2024
@Fidget-Spinner @markshannon @mrahtz
pythongh-117139: Convert the evaluation stack to stack refs (python#1…
a8eaa06
…18450)

This PR sets up tagged pointers for CPython.

The general idea is to create a separate struct _PyStackRef for everything on the evaluation stack to store the bits. This forces the C compiler to warn us if we try to cast things or pull things out of the struct directly.

Only for free threading: We tag the low bit if something is deferred - that means we skip incref and decref operations on it. This behavior may change in the future if Mark's plans to defer all objects in the interpreter loop pans out.

This implies a strict stack reference discipline is required. ALL incref and decref operations on stackrefs must use the stackref variants. It is unsafe to untag something then do normal incref/decref ops on it.

The new incref and decref variants are called dup and close. They mimic a "handle" API operating on these stackrefs.

Please read Include/internal/pycore_stackref.h for more information!

---------

Co-authored-by: Mark Shannon <[email protected]>
mrahtz pushed a commit to mrahtz/cpython that referenced this pull request Jun 30, 2024
@Zheaoli @Fidget-Spinner @mrahtz
pythongh-121082: Fix build failure when the developer use `--enable-p…
794f146
…ystats` arguments in configuration command after python#118450 (python#121083)



Signed-off-by: Manjusaka <[email protected]>
Co-authored-by: Ken Jin <[email protected]>
This was referenced Jul 2, 2024
Stackrefs (#118450) introduced a large performance regression on Windows #121263
Closed
gh-121263: Macro-ify most stackref functions for MSVC #121270
Merged
estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
@Fidget-Spinner @markshannon @estyxx
pythongh-117139: Convert the evaluation stack to stack refs (python#1…
6f411b0
…18450)

This PR sets up tagged pointers for CPython.

The general idea is to create a separate struct _PyStackRef for everything on the evaluation stack to store the bits. This forces the C compiler to warn us if we try to cast things or pull things out of the struct directly.

Only for free threading: We tag the low bit if something is deferred - that means we skip incref and decref operations on it. This behavior may change in the future if Mark's plans to defer all objects in the interpreter loop pans out.

This implies a strict stack reference discipline is required. ALL incref and decref operations on stackrefs must use the stackref variants. It is unsafe to untag something then do normal incref/decref ops on it.

The new incref and decref variants are called dup and close. They mimic a "handle" API operating on these stackrefs.

Please read Include/internal/pycore_stackref.h for more information!

---------

Co-authored-by: Mark Shannon <[email protected]>
estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
@Zheaoli @Fidget-Spinner @estyxx
pythongh-121082: Fix build failure when the developer use `--enable-p…
7aea987
…ystats` arguments in configuration command after python#118450 (python#121083)



Signed-off-by: Manjusaka <[email protected]>
Co-authored-by: Ken Jin <[email protected]>
@scoder scoder mentioned this pull request Mar 6, 2025
Cython cannot use "pycore_frame.h" in Py3.14a4 #130931
Open
@taegyunkim taegyunkim mentioned this pull request Dec 8, 2025
feat(profiling): support Python 3.14 DataDog/dd-trace-py#15546
Merged
taegyunkim added a commit to DataDog/dd-trace-py that referenced this pull request Dec 11, 2025
@taegyunkim @brettlangdon
feat(profiling): support Python 3.14 (#15546)
1823291
## Description

This PR adds support for Python 3.14 in the profiler by updating it to
handle CPython internal changes.

### Key CPython changes addressed 

**`_PyInterpreterFrame` Structure Changes**
1. Moved from `Include/internal/pycore_frame.h` to
`Include/internal/pycore_interpframe_structs.h`
2. `PyObject *f_executable` and `PyObject *f_funcobj` changed to
`_PyStackRef` type. Profilers like us now need to clear the LSB of these
fields to get the `PyObject*`. See
python/cpython#123923 for details
3. `int stacktop` field removed, replaced with `_PyStackRef
*stackpointer` pointer. See
python/cpython#121923 (GH-120024) for details
4. `PyObject *localsplus[1]` changed to `_PyStackRef localsplus[1]`. See
python/cpython#118450 (gh-117139) for details

**`FutureObj`/`TaskObj` Changes**
1. Added fields: `awaited_by`, `is_task`, `awaited_by_is_set` in
`FutureObj_HEAD` macro
2. Added `struct llist_node_task_node` field for linked-list storage

**Asyncio Task Storage Changes**

Prior to Python 3.14, 
- All tasks are stored in `_scheduled_tasks` WeakSet
([exported](https://github.com/python/cpython/blob/e96367da1fdc1e1cf17ca523e93a127b1961b443/Modules/_asynciomodule.c#L3738)
from C extension)
- Eager tasks are stored in `_eager_tasks` set
([exported](https://github.com/python/cpython/blob/e96367da1fdc1e1cf17ca523e93a127b1961b443/Modules/_asynciomodule.c#L3742)
from C extension)

From Python 3.14,
- Native `asyncio.Tasks` are stored in a linked-list (`struct
llist_node`) per thread and per interpreter
-
[Per-thread](https://github.com/python/cpython/blob/0114178911f8713bfcb935ff5542fe61b4a5d551/Include/internal/pycore_tstate.h#L46):
`tstate->asyncio_tasks_head` (in `_PyThreadStateImpl`)
-
[Per-interpreter](https://github.com/python/cpython/blob/0114178911f8713bfcb935ff5542fe61b4a5d551/Include/internal/pycore_interp_structs.h#L897):
`interp->asyncio_tasks_head` (for lingering tasks)
- Each `TaskObj` has a `task_node` field with `next` and `prev` pointers
- Third-party tasks: Still stored in Python-level `_scheduled_tasks`
WeakSet (now Python-only, not exported from C extension)
- Eager tasks:  Still stored in Python-level `_eager_tasks` set


### Implementation Summary

- **Frame reading** (`frame.h`, `frame.cc`): Updated header includes to
use `pycore_interpframe_structs.h` for Python 3.14+. Implemented tagged
pointer handling: clear LSB of `f_executable` to recover `PyObject*`
(per gh-123923). Replaced `stacktop` field access with `stackpointer`
pointer arithmetic for stack depth calculation. Updated `PyGen_yf()` to
use `_PyStackRef` and `stackpointer[-1]` instead of
`localsplus[stacktop-1]`. Added handling for
`FRAME_OWNED_BY_INTERPRETER` frame type (introduced in 3.14).

- **Task structures** (`cpython/tasks.h`): Added Python 3.14+
`FutureObj_HEAD` macro with new fields: `awaited_by`, `is_task`,
`awaited_by_is_set`. Added `struct llist_node task_node` field to
`TaskObj` for linked-list storage. Updated `PyGen_yf()` implementation
to handle `_PyStackRef` and `stackpointer` instead of `stacktop`.

- **Asyncio discovery** (`tasks.h`, `threads.h`): Implemented
`get_tasks_from_linked_list()` to safely iterate over circular
linked-lists with iteration limits (`MAX_ITERATIONS = 2 << 15`). Added
`get_tasks_from_thread_linked_list()` to read tasks from
`_PyThreadStateImpl.asyncio_tasks_head` (per-thread active tasks). Added
`get_tasks_from_interpreter_linked_list()` to read lingering tasks from
`PyInterpreterState.asyncio_tasks_head` (per-interpreter). Updated
`get_all_tasks()` to handle both linked-list (native `asyncio.Task`
instances) and WeakSet (third-party tasks).

- **Python integration** (`_asyncio.py`): Added compatibility handling
for `BaseDefaultEventLoopPolicy` → `_BaseDefaultEventLoopPolicy` rename
in 3.14. Updated `_scheduled_tasks` access to handle Python-only WeakSet
(no longer exported from C extension in 3.14+).

## Testing

All existing tests pass except for
tests/profiling/collector/test_memalloc.py which needed some edits.

## Risks

<!-- Note any risks associated with this change, or "None" if no risks
-->

## Additional Notes

---------

Co-authored-by: Brett Langdon <[email protected]>
navytux added a commit to navytux/pygolang that referenced this pull request Mar 3, 2026
@navytux
golang: Fix XPyFrame_WhiteoutFastLocal for py3.14
e9ce7b0
Problem 1:

    golang/_golang.cpp: In function ‘void XPyFrame_WhiteoutFastLocal(PyFrameObject*, PyObject*)’:
    golang/_golang.cpp:1572:43: error: invalid use of incomplete type ‘_PyInterpreterFrame’ {aka ‘struct _PyInterpreterFrame’}
     1572 |                                 f->f_frame->localsplus;
          |                                           ^~
    In file included from /home/kirr/local/py3.14/include/python3.14/pyframe.h:19,
                     from /home/kirr/local/py3.14/include/python3.14/Python.h:113,
                     from golang/_golang.cpp:150:
    /home/kirr/local/py3.14/include/python3.14/cpython/pyframe.h:25:8: note: forward declaration of ‘_PyInterpreterFrame’ {aka ‘struct _PyInterpreterFrame’}
       25 | struct _PyInterpreterFrame;
          |        ^~~~~~~~~~~~~~~~~~~

-> include internal/pycore_interpframe.h like we already do with e.g. internal/pycore_frame.h .

Problem 2:

    golang/_golang.cpp: In function ‘void XPyFrame_WhiteoutFastLocal(PyFrameObject*, PyObject*)’:
    golang/_golang.cpp:1575:45: error: cannot convert ‘_PyStackRef*’ to ‘PyObject**’ {aka ‘_object**’} in initialization
     1575 |                                 f->f_frame->localsplus;
          |                                 ~~~~~~~~~~~~^~~~~~~~~~
          |                                             |
          |                                             _PyStackRef*

It turns out _PyInterpreterFrame.localsplus was changed from PyObject to _PyStackRef:

    python/cpython@22b0de2755ee2
    python/cpython#118450
    python/cpython#117139

-> Adjust the code to work with localsplus as _PyStackRef on py3.14+ .

/reviewed-by @jerome
/reviewed-on https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@colesbury colesbury colesbury approved these changes
@gvanrossum gvanrossum Awaiting requested review from gvanrossum
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently
@ncoghlan ncoghlan Awaiting requested review from ncoghlan
@warsaw warsaw Awaiting requested review from warsaw
@methane methane Awaiting requested review from methane
@brandtbucher brandtbucher Awaiting requested review from brandtbucher brandtbucher is a code owner
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
+1 more reviewer
@nineteendo nineteendo nineteendo left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

topic-free-threading

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@Fidget-Spinner @gvanrossum @colesbury @markshannon @bedevere-bot @nineteendo
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.