Skip to content

Commit 26d5559

Browse files
committed
Address review
1 parent be38623 commit 26d5559

File tree

4 files changed

+28
-22
lines changed

4 files changed

+28
-22
lines changed

InternalDocs/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,3 @@ it is not, please report that through the
2121
[The Source Code Locations Table](locations.md)
2222

2323
[Exception Handling](exception_handling.md)
24-
25-
[The Virtual Machine](vm-state.md)

InternalDocs/frames.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ This seems to provide the best performance without excessive complexity.
3636
The specials have a fixed size, so the offset of the locals is know. The
3737
interpreter needs to hold two pointers, a frame pointer and a stack pointer.
3838

39+
### Fast locals and evaluation stack
40+
41+
The frame contains a single array of object pointers, `localsplus`,
42+
which contains both the fast locals and the stack. The top of the
43+
stack, including the locals, is indicated by `stacktop`.
44+
For example, in a function with three locals, if the stack contains
45+
one value, `frame->stacktop == 4`.
46+
47+
The interpreters share an implementation which uses the same memory
48+
but caches the depth (as a pointer) in a C local, `stack_pointer`.
49+
We aren't sure yet exactly how the JIT will implement the stack;
50+
likely some of the values near the top of the stack will be held in registers.
51+
52+
3953
#### Alternative layout
4054

4155
An alternative layout that was used for part of 3.11 alpha was:
@@ -124,6 +138,8 @@ if the frame were to resume. After `frame.f_lineno` is set, `instr_ptr` points t
124138
the next instruction to be executed. During a call to a python function,
125139
`instr_ptr` points to the call instruction, because this is what we would expect
126140
to see in an exception traceback.
141+
Dispatching on `instr_ptr` would be very inefficient, so in Tier 1 we cache the
142+
upcoming value of `instr_ptr` in the C local `next_instr`.
127143

128144
The `return_offset` field determines where a `RETURN` should go in the caller,
129145
relative to `instr_ptr`. It is only meaningful to the callee, so it needs to

InternalDocs/tier2_engine.md renamed to Python/tier2_engine.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,13 @@ TO DO.
148148
The implementation will change soon, so there is no point in
149149
documenting it until then.
150150

151+
152+
# Tier 2 IR format
153+
154+
The tier 2 IR (Internal Representation) format is also the basis for the Tier 2 interpreter (though the two formats may eventually differ). This format is also used as the input to the machine code generator (the JIT compiler).
155+
156+
Tier 2 IR entries are all the same size; there is no equivalent to `EXTENDED_ARG` or trailing inline cache entries. Each instruction is a struct with the following fields (all integers of varying sizes):
157+
158+
- **opcode**: Sometimes the same as a Tier 1 opcode, sometimes a separate micro opcode. Tier 2 opcodes are 9 bits (as opposed to Tier 1 opcodes, which fit in 8 bits). By convention, Tier 2 opcode names start with `_`.
159+
- **oparg**: The argument. Usually the same as the Tier 1 oparg after expansion of `EXTENDED_ARG` prefixes. Up to 32 bits.
160+
- **operand**: An additional argument, Typically the value of *one* cache item from the Tier 1 inline cache, up to 64 bits.

InternalDocs/vm-state.md renamed to Python/vm-state.md

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@
33
## Definition of Tiers
44

55
- **Tier 1** is the classic Python bytecode interpreter.
6-
This includes the specializing [adaptive interpreter](adaptive.md).
7-
- **Tier 2**, also known as the micro-instruction ("uop") interpreter, is a new interpreter with a different instruction format.
6+
This includes the specializing [adaptive interpreter](../InternalDocs/adaptive.md).
7+
- **Tier 2**, also known as the micro-instruction ("uop") interpreter, is a new execution engine.
88
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.
99

1010

11-
# Frame state
12-
13-
Almost all interpreter state is nominally stored in the frame structure.
14-
A pointer to the current frame is held in `frame`, for more information about what `frame` contains see [Frames](frames.md):
1511

1612
# Thread state and interpreter state
1713

@@ -23,20 +19,6 @@ The thread state is also used to access the **interpreter state** (`tstate->inte
2319
The interpreter state also holds the optimizer state (`optimizer` and some counters).
2420
Note that the eval breaker may be moved to the thread state soon as part of the multicore (PEP 703) work.
2521

26-
## Fast locals and evaluation stack
27-
28-
The frame contains a single array of object pointers, `localsplus`, which contains both the fast locals and the stack.
29-
The top of the stack, including the locals, is indicated by `stacktop`.
30-
For example, in a function with three locals, if the stack contains one value, `frame->stacktop == 4`.
31-
32-
The interpreters share an implementation which uses the same memory but caches the depth (as a pointer) in a C local, `stack_pointer`.
33-
We aren't sure yet exactly how the JIT will implement the stack; likely some of the values near the top of the stack will be held in registers.
34-
35-
## Instruction pointer
36-
37-
The canonical, in-memory, representation of the instruction pointer is `frame->instr_ptr`.
38-
It always points to an instruction in the bytecode array of the frame's code object.
39-
Dispatching on `frame->instr_ptr` would be very inefficient, so in Tier 1 we cache the upcoming value of `frame->instr_ptr` in the C local `next_instr`.
4022

4123
## Tier 2
4224

0 commit comments

Comments
 (0)