Skip to content

Consistently spill the evaluation stack and save the stack pointer across escaping calls. #128681

@markshannon

Description

@markshannon

Currently we mostly spill the stack (saving it to memory) and save the stack pointer (saving to frame->stackpointer) but not always.
Calls to Py_DECREF, PyStackRef_CLOSE and related functions can escape (calling arbitrary Python code and causing the GC to run), but we do not spill the stack across these "call"s.

Spilling the stack across all escaping calls is a bit of a challenge, adding a fair bit of additional complexity to the code generators.
But it is worth it as it allows means that the GC is guaranteed to be able to see every reference on the stack(s). This means that we do not need to make conservative approximations about what references are live in a frame, nor do we need to NULL out unused stack values.
It also allows us to defer many, many more references than we currently do.

### Tasks
- [ ] Strengthen the code analyzer to enforce stack discipline on lifetimes of references on the stack: references nearer the top of the stack must be destroyed no later than references lower down the stack.
- [ ] Treat all explicit calls to `Py_DECREF`, `PyStackRef_CLOSE` as escaping
- [ ] Fix up `DECREF_INPUTS` to manage the stack in a way that is safe, spilling where necessary, when closing references.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions