Skip to content

Commit 82aa257

Browse files
committed
docs: describe what the automatic compiler takes and turns down
The README's JIT section covered only `__jit__()`. It now also covers the `aot` feature, the switches that turn it on, the shapes it compiles and the shapes it refuses, what happens where a machine word runs out, and why compiled code is invisible to a tracer. Assisted-by: Claude
1 parent 6c62636 commit 82aa257

1 file changed

Lines changed: 46 additions & 5 deletions

File tree

README.md

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,21 +145,62 @@ cargo build --release --target wasm32-wasip1 --features="freeze-stdlib"
145145
146146
### JIT (Just in time) compiler
147147

148-
RustPython has a **very** experimental JIT compiler that compile python functions into native code.
148+
RustPython has a **very** experimental JIT compiler that compiles python functions into native code.
149+
It comes in two forms: an automatic one that tries every function once, as it is first called, and
150+
an explicit `__jit__()` that compiles the one function it is called on.
149151

150152
#### Building
151153

152-
By default the JIT compiler isn't enabled, it's enabled with the `jit` cargo feature.
154+
Neither is built by default.
153155

154156
```bash
155-
cargo run --features jit
157+
cargo run --features aot # automatic, and the explicit one with it
158+
cargo run --features jit # explicit `__jit__()` alone
156159
```
157160

158161
This requires autoconf, automake, libtool, and clang to be installed.
159162

160-
#### Using
163+
#### Using the automatic compiler
161164

162-
To compile a function, call `__jit__()` on it.
165+
A build that has it still has to be switched on, with `-X aot=1`, `RUSTPYTHON_AOT=1`
166+
or `PYTHON_JIT=1`; `-X aot=0` and `=0` switch it back off. Every function is then
167+
offered to the compiler the first time it is called. The attempt happens once,
168+
so a function it turns down costs that one attempt and is interpreted from then on.
169+
170+
`sys._jit.is_available()` reports whether the compiler was built in, `is_enabled()`
171+
whether it is switched on, and `_stats()` returns `(compiled, rejected, deoptimized)`
172+
for the functions it has looked at so far — a RustPython extension.
173+
174+
#### What it compiles
175+
176+
Annotated scalar functions, and nothing else. The argument and return types come
177+
from the annotations rather than from the values a call arrives with, so a function
178+
without them is turned down however it is called.
179+
180+
Taken: `int`, `float` and `bool` arguments, locals and return values; arithmetic,
181+
comparison and boolean operators; `if`, `while`, and the assignments between them.
182+
183+
Turned down: missing annotations, `*args`/`**kwargs`, closures, generators and
184+
coroutines, `try`/`except`, attributes and methods, containers, `for`, calls to
185+
anything but the function itself, and expressions that merge with an operand still
186+
on the stack, such as a conditional expression. A call a function makes to itself
187+
is compiled only by `__jit__()`; the automatic path turns those down too, because
188+
the global it goes through can be rebound between one call and the next.
189+
190+
Where a machine word runs out — an overflow, a division by zero, a shift past the
191+
width, a power with no real answer — the compiled code hands the frame back at the
192+
instruction it could not do, with the values it had, and the interpreter carries on
193+
from there. The native code is dropped at that point, and the function is
194+
interpreted afterwards.
195+
196+
Compiled code runs with no python frame. That is why `sys._jit.is_active()` is
197+
always `False`, why such a call reports no line and no return to `sys.settrace` or
198+
`sys.monitoring`, and why a call is interpreted, and left uncompiled, while either
199+
of those is installed.
200+
201+
#### Using `__jit__()`
202+
203+
To compile a single function, call `__jit__()` on it. This needs only the `jit` feature.
163204

164205
```python
165206
def foo():

0 commit comments

Comments
 (0)