Skip to content
2 changes: 2 additions & 0 deletions InternalDocs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ it is not, please report that through the
[The Source Code Locations Table](locations.md)

[Exception Handling](exception_handling.md)

[Virtual Machine](vm-state.md)
File renamed without changes.
14 changes: 2 additions & 12 deletions Python/vm-state.md → InternalDocs/vm-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,12 @@
- **Tier 1** is the classic Python bytecode interpreter.
This includes the specializing adaptive interpreter described in [PEP 659](https://peps.python.org/pep-0659/) and introduced in Python 3.11.
- **Tier 2**, also known as the micro-instruction ("uop") interpreter, is a new interpreter with a different instruction format.
It will be introduced in Python 3.13, and also forms the basis for a JIT using copy-and-patch technology that is likely to be introduced at the same time (but, unlike the Tier 2 interpreter, hasn't landed in the main branch yet).
It was introduced in Python 3.13, and also forms the basis for a JIT using copy-and-patch technology. See [Tier 2](tier2_engine.md) for more information.

# Frame state

Almost all interpreter state is nominally stored in the frame structure.
A pointer to the current frame is held in `frame`. It contains:

- **local variables** (a.k.a. "fast locals")
- **evaluation stack** (tacked onto the end of the locals)
- **stack top** (an integer giving the top of the evaluation stack)
- **instruction pointer**
- **code object**, which holds things like the array of instructions, lists of constants and names referenced by certain instructions, the exception handling table, and the table that translates instruction offsets to line numbers
- **return offset**, only relevant during calls, telling the interpreter where to return

There are some other fields in the frame structure of less importance; notably frames are linked together in a singly-linked list via the `previous` pointer, pointing from callee to caller.
The frame also holds a pointer to the current function, globals, builtins, and the locals converted to dict (used to support the `locals()` built-in).
A pointer to the current frame is held in `frame`, for more information about what `frame` contains see [Frames](frames.md):

Copy link
Member

@iritkatriel iritkatriel Sep 27, 2024

Choose a reason for hiding this comment

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

CC @markshannon

I can't comment on lines that haven't changed, so this is for a number of comments on vm-state.md.

L 21: The interpreters share an implementation of what? The frame? Caches the depth - is this stack depth?

L 40: Add a link to exception_handling.md.

L45: Not sure what you mean here: "The implementation of jumps within a single Tier 2 superblock/trace is just that, an implementation."

L51: "within the superblock" is repeated twice.
L52: what cannot be modified?

I think it might be worth moving the contents of the "Thread state and interpreter state" section to the beginning, as a high level overview of the components of the state, and then drill into the parts.

The "Tier 2 IR format" section doesn't seem to belong to the vm-state topic at all.

Copy link
Member

Choose a reason for hiding this comment

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

The interpreters share an implementation of what?

Both tier 1 and tier 2 use the same canonical in-memory representation. Tier 2 might store some values temporarily in registers, but that should be invisible to other code. The reason this is noteworthy is that other VMs, e.g. HotSpot can have different frame layouts for the compiler and interpreter.

## Fast locals and evaluation stack

Expand Down