114 Commits

Author SHA1 Message Date
Mark Shannon 70bd1c2dd2 GH-143732: SEND specialization (GH-148963)
* SEND specialization. Adds 2 new specialized instructions:

* SEND_VIRTUAL: for sends to virtual iterators e.g lists and tuples
* SEND_ASYNC_GEN: for sends to async generators

Tweak FOR_ITER_VIRTUAL so that SEND_VIRTUAL and FOR_ITER_VIRTUAL use equivalent guards
2026-05-05 15:19:16 +01:00
Pablo Galindo Salgado 9a268e3e33 gh-98894: Restore function entry/exit DTrace probes (#142397)
The function__entry and function__return probes stopped working in Python 3.11
when the interpreter was restructured around the new bytecode system. This change
restores these probes by adding DTRACE_FUNCTION_ENTRY() at the start_frame label
in bytecodes.c and DTRACE_FUNCTION_RETURN() in the RETURN_VALUE and YIELD_VALUE
instructions. The helper functions are defined in ceval.c and extract the
filename, function name, and line number from the frame before firing the probe.

This builds on the approach from https://github.com/python/cpython/pull/125019
but avoids modifying the JIT template since the JIT does not currently support
DTrace. The macros are conditionally compiled with WITH_DTRACE and are no-ops
otherwise. The tests have been updated to use modern opcode names (CALL, CALL_KW,
CALL_FUNCTION_EX) and a new bpftrace backend was added for Linux CI alongside
the existing SystemTap tests. Line probe tests were removed since that probe
was never restored after 3.11.
2026-05-05 00:29:55 +00:00
Diego Russo c7b7ca2cd5 GH-126910: Add gdb support for unwinding JIT frames (#146071)
Co-authored-by: Pablo Galindo Salgado <pablogsal@gmail.com>
2026-05-02 13:42:03 +00:00
Dino Viehland c0af5c024b gh-146031: Allow keeping specialization enabled when specifying eval frame function (#146032)
Allow keeping specialization enabled when specifying eval frame function
2026-04-16 09:44:26 -07:00
Pieter Eendebak 95cbd4a232 gh-146393: Optimize float division operations by mutating uniquely-referenced operands in place (JIT only) (GH-146397)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 02:08:04 +08:00
Pieter Eendebak 48317feec8 gh-146640: Optimize int operations by mutating uniquely-referenced operands in place (JIT only) (GH-146641) 2026-04-03 23:23:04 +08:00
Pieter Eendebak 951675c18a gh-146306: JIT: Optimize float operations by mutating uniquely-referenced operands in place (GH-146307)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:16:02 +08:00
Sam Gross a01694dacd gh-120321: Make gi_yieldfrom thread-safe in free-threading build (#144292)
Add a FRAME_SUSPENDED_YIELD_FROM_LOCKED state that acts as a brief
lock, preventing other threads from transitioning the frame state
while gen_getyieldfrom reads the yield-from object off the stack.
2026-01-30 12:20:27 -05:00
Sam Gross 6ea3f8cd7f gh-144289: Remove ENABLE_SPECIALIZATION_FT (gh-144290)
Now that the specializing interpreter works with free threading,
replace ENABLE_SPECIALIZATION_FT with ENABLE_SPECIALIZATION and
replace requires_specialization_ft with requires_specialization.

Also limit the uniquely referenced check to FOR_ITER_RANGE. It's not
necessary for FOR_ITER_GEN and would cause test_for_iter_gen to fail.
2026-01-27 17:52:50 -05:00
Sam Gross 6b4538192d gh-120321: Add missing "return false" in gen_try_set_executing (gh-144291)
We didn't catch this because of a combination of:

1) falling through to the if-statement below works
2) we only specialized FOR_ITER_GEN for uniquely referenced generators,
   so we didn't trigger the non-thread-safe behavior.
2026-01-27 16:38:50 -05:00
Mark Shannon d77aaa7311 GH-139109: Partial reworking of JIT data structures (GH-144105)
* Halve size of buffers by reusing combined trace + optimizer buffers for TOS caching
* Add simple buffer struct for more maintainable handling of buffers
* Decouple JIT structs from thread state struct
* Ensure terminator is added to trace, when optimizer gives up
2026-01-22 10:55:49 +00:00
Ken Jin e370c8db52 gh-143123: Protect against recursive tracer calls/finalization (GH-143126)
* Stronger check for recursive traces

* Add a stop_tracing field

* Stop early when tracing exceptions
2026-01-14 12:23:14 +00:00
Ken Jin e0fb278064 gh-143421: Allocate all JIT state in one go (GH-143626) 2026-01-09 19:00:49 +00:00
Dino Viehland bfc3d8d77f gh-143531: Use macro to check if PEP 523 is hooked (#143532)
Use macro to check if PEP 523 is hooked
2026-01-07 13:26:19 -08:00
Chris Eibl be3c131640 GH-139922: Tail calling for MSVC (VS 2026) (GH-143068)
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Co-authored-by: Brandt Bucher <brandt@python.org>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
2025-12-22 23:01:34 +00:00
Sam Gross 08bc03ff2a gh-120321: Make gi_frame_state transitions atomic in FT build (gh-142599)
This makes generator frame state transitions atomic in the free
threading build, which avoids segfaults when trying to execute
a generator from multiple threads concurrently.

There are still a few operations that aren't thread-safe and may crash
if performed concurrently on the same generator/coroutine:

 * Accessing gi_yieldfrom/cr_await/ag_await
 * Accessing gi_frame/cr_frame/ag_frame
 * Async generator operations
2025-12-19 19:10:37 +00:00
Ken Jin 0ac4e6c6cd gh-134584: Remove custom float decref ops (GH-142576) 2025-12-15 19:38:58 +00:00
Mark Shannon 4eab90f4f3 GH-140683: JIT: Improve machine code for loading smaller constants on AArch64. (GH-142511)
* Use movz and movk instructions for loading 16 and 32 bit operands and oparg.
* Loading of 64 bit operands is unchanged.
2025-12-11 12:33:39 +00:00
Mark Shannon 469f191a85 GH-135379: Top of stack caching for the JIT. (GH-135465)
Uses three registers to cache values at the top of the evaluation stack
This significantly reduces memory traffic for smaller, more common uops.
2025-12-11 10:32:52 +00:00
Mark Shannon 62423c9c36 GH-141794: Limit size of generated machine code. (GH-142228)
* Factor out bodies of the largest uops, to reduce jit code size.
* Factor out common assert, also reducing jit code size.
* Limit size of jitted code for a single executor to 1MB.
2025-12-03 17:43:35 +00:00
Mark Shannon b420f6be53 GH-139109: Support switch/case dispatch with the tracing interpreter. (GH-141703) 2025-11-18 13:31:48 +00:00
Ken Jin 4fa80ce74c gh-139109: A new tracing JIT compiler frontend for CPython (GH-140310)
This PR changes the current JIT model from trace projection to trace recording. Benchmarking: better pyperformance (about 1.7% overall) geomean versus current https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20251108-3.15.0a1%2B-7e2bc1d-JIT/bm-20251108-vultr-x86_64-Fidget%252dSpinner-tracing_jit-3.15.0a1%2B-7e2bc1d-vs-base.svg, 100% faster Richards on the most improved benchmark versus the current JIT. Slowdown of about 10-15% on the worst benchmark versus the current JIT. **Note: the fastest version isn't the one merged, as it relies on fixing bugs in the specializing interpreter, which is left to another PR**. The speedup in the merged version is about 1.1%. https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20251112-3.15.0a1%2B-f8a764a-JIT/bm-20251112-vultr-x86_64-Fidget%252dSpinner-tracing_jit-3.15.0a1%2B-f8a764a-vs-base.svg

Stats: 50% more uops executed, 30% more traces entered the last time we ran them. It also suggests our trace lengths for a real trace recording JIT are too short, as a lot of trace too long aborts https://github.com/facebookexperimental/free-threading-benchmarking/blob/main/results/bm-20251023-3.15.0a1%2B-eb73378-CLANG%2CJIT/bm-20251023-vultr-x86_64-Fidget%252dSpinner-tracing_jit-3.15.0a1%2B-eb73378-pystats-vs-base.md .

This new JIT frontend is already able to record/execute significantly more instructions than the previous JIT frontend. In this PR, we are now able to record through custom dunders, simple object creation, generators, etc. None of these were done by the old JIT frontend. Some custom dunders uops were discovered to be broken as part of this work gh-140277

The optimizer stack space check is disabled, as it's no longer valid to deal with underflow.

Pros:
* Ignoring the generated tracer code as it's automatically created, this is only additional 1k lines of code. The maintenance burden is handled by the DSL and code generator.
* `optimizer.c` is now significantly simpler, as we don't have to do strange things to recover the bytecode from a trace.
* The new JIT frontend is able to handle a lot more control-flow than the old one.
* Tracing is very low overhead. We use the tail calling interpreter/computed goto interpreter to switch between tracing mode and non-tracing mode. I call this mechanism dual dispatch, as we have two dispatch tables dispatching to each other. Specialization is still enabled while tracing.
* Better handling of polymorphism. We leverage the specializing interpreter for this.

Cons:
* (For now) requires tail calling interpreter or computed gotos. This means no Windows JIT for now :(. Not to fret, tail calling is coming soon to Windows though https://github.com/python/cpython/pull/139962

Design:
* After each instruction, the `record_previous_inst` function/label is executed. This does as the name suggests.
* The tracing interpreter lowers bytecode to uops directly so that it can obtain "fresh" values at the point of lowering.
* The tracing version behaves nearly identical to the normal interpreter, in fact it even has specialization! This allows it to run without much of a slowdown when tracing. The actual cost of tracing is only a function call and writes to memory.
* The tracing interpreter uses the specializing interpreter's deopt to naturally form the side exit chains. This allows it to side exit chain effectively, without repeating much code. We force a re-specializing when tracing a deopt.
* The tracing interpreter can even handle goto errors/exceptions, but I chose to disable them for now as it's not tested.
* Because we do not share interpreter dispatch, there is should be no significant slowdown to the original specializing interpreter on tailcall and computed got with JIT disabled. With JIT enabled, there might be a slowdown in the form of the JIT trying to trace.
* Things that could have dynamic instruction pointer effects are guarded on. The guard deopts to a new instruction --- `_DYNAMIC_EXIT`.
2025-11-13 18:08:32 +00:00
Neil Schemenauer c98c5b3449 gh-131253: free-threaded build support for pystats (gh-137189)
Allow the --enable-pystats build option to be used with free-threading.  The
stats are now stored on a per-interpreter basis, rather than process global.
For free-threaded builds, the stats structure is allocated per-thread and
then periodically merged into the per-interpreter stats structure (on thread
exit or when the reporting function is called). Most of the pystats related
code has be moved into the file Python/pystats.c.
2025-11-03 11:36:37 -08:00
Krishna Chaitanya 2f60b8f02f gh-140513: Fail to compile if _Py_TAIL_CALL_INTERP is set but preserve_none and musttail do not exist. (GH-140548)
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
2025-11-01 16:41:23 +00:00
Ken Jin a716091227 gh-140104: Set next_instr properly in the JIT during exceptions (GH-140233)
Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com>
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
2025-10-27 18:26:47 +00:00
Ken Jin a269e691de gh-139109: Dynamic opcode targets (GH-139111)
Make opcode targets table dynamic
2025-09-18 14:12:07 +01:00
Victor Stinner 6504f20cce gh-135755: Make Py_TAIL_CALL_INTERP macro private (#138981)
Rename Py_TAIL_CALL_INTERP to _Py_TAIL_CALL_INTERP.
2025-09-18 14:33:07 +02:00
Mark Shannon a8d9d94784 GH-137959: Replace shim code in jitted code with a single trampoline function. (GH-137961) 2025-08-21 10:40:53 +01:00
Mark Shannon af15e1d13e GH-132532: Add new DSL macros to better declare semantics of exits at ends of instructions/uops. (GH-137098) 2025-08-09 15:41:28 +01:00
Mark Shannon e7b55f564d GH-136410: Faster side exits by using a cold exit stub (GH-136411) 2025-08-01 16:26:07 +01:00
Mark Shannon ac7d5ba96e GH-133231: Changes to executor management to support proposed sys._jit module (GH-133287)
* Track the current executor, not the previous one, on the thread-state. 

* Batch executors for deallocation to avoid having to constantly incref executors; this is an ad-hoc form of deferred reference counting.
2025-05-04 10:05:35 +01:00
Ken Jin 6430c634da gh-132758: Fix tail call and pystats builds (GH-132759) 2025-04-23 18:17:35 +08:00
Mark Shannon 7099c75550 GH-131498: Cases generator: manage stacks automatically (GH-132074) 2025-04-04 17:59:36 +01:00
Mark Shannon 2bef8ea8ea GH-127705: Use _PyStackRefs in the default build. (GH-127875) 2025-03-10 14:06:56 +00:00
Ken Jin 359c7dde3b gh-129989: Properly disable tailcall interp in configure (GH-129991)
Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-02-16 03:01:24 +08:00
Ken Jin 1b27f36eb0 gh-129819: Allow tier2/JIT and tailcall (GH-129820) 2025-02-13 02:18:36 +08:00
Mark Shannon 72f56654d0 GH-128682: Account for escapes in DECREF_INPUTS (GH-129953)
* Handle escapes in DECREF_INPUTS

* Mark a few more functions as escaping

* Replace DECREF_INPUTS with PyStackRef_CLOSE where possible
2025-02-12 17:44:59 +00:00
Brandt Bucher 70e387c990 GH-129709: Clean up tier two (GH-129710) 2025-02-07 09:52:49 -08:00
Brandt Bucher fbaa6c8ff0 GH-129763: Remove the LLTRACE macro (GH-129764) 2025-02-07 08:49:51 -08:00
Ken Jin cb640b659e gh-128563: A new tail-calling interpreter (GH-128718)
Co-authored-by: Garrett Gu <garrettgu777@gmail.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
2025-02-06 23:21:57 +08:00
Mark Shannon 96ff4c2486 GH-128682: Mark two more macros as escaping. (GH-129645)
Expand out SETLOCAL so that code generator can see the decref. Mark Py_CLEAR as escaping
2025-02-04 14:00:51 +00:00
Mark Shannon 54f74b80ae GH-128563: Move some labels, to simplify implementing tailcalling interpreter. (GH-129525) 2025-01-31 17:13:20 +00:00
Ken Jin 86c1a60d5a gh-128563: Move GO_TO_INSTRUCTION and PREDICT to cases generator (GH-129115) 2025-01-22 09:22:25 +08:00
Ken Jin 5809b25909 gh-128563: Move lltrace into the frame struct (GH-129113) 2025-01-21 22:17:15 +08:00
Mark Shannon f5b6356a11 GH-128563: Add new frame owner type for interpreter entry frames (GH-129078)
Add new frame owner type for interpreter entry frames
2025-01-21 10:15:02 +00:00
Mark Shannon f826beca0c GH-128375: Better instrument for FOR_ITER (GH-128445) 2025-01-06 17:54:47 +00:00
Mark Shannon 128cc47fbd GH-127705: Add debug mode for _PyStackRefs inspired by HPy debug mode (GH-128121) 2024-12-20 16:52:20 +00:00
Kumar Aditya 91c55085a9 gh-128033: change PyMutex_LockFast to take PyMutex as argument (#128054)
Change `PyMutex_LockFast` to take `PyMutex` as argument.
2024-12-18 20:49:00 +05:30
Sam Gross 71ede1142d gh-115999: Add free-threaded specialization for STORE_SUBSCR (#127169)
The specialization only depends on the type, so no special thread-safety
considerations there.

STORE_SUBSCR_LIST_INT needs to lock the list before modifying it.

`_PyDict_SetItem_Take2` already internally locks the dictionary using a
critical section.
2024-11-26 16:46:06 -05:00
Ken Jin 6293d00e72 gh-120619: Strength reduce function guards, support 2-operand uop forms (GH-124846)
Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
2024-11-09 11:35:33 +08:00