Commit Graph

8992 Commits

Author SHA1 Message Date
VanshAgarwal24036 67d3d0344f gh-143089: Fix ParamSpec default examples to use list instead of tuple (#143179) 2026-01-07 19:32:44 -08:00
Sam Gross 98e55d70bc gh-132070: Fix PyObject_Realloc thread-safety in free threaded Python (gh-143441)
The PyObject header reference count fields must be initialized using
atomic operations because they may be concurrently read by another
thread (e.g., from `_Py_TryIncref`).
2026-01-06 15:55:37 -05:00
Sam Gross 71119a164c gh-129824: Fix data race in _PyBuiltins_AddExceptions with subinterpreters (gh-143446) 2026-01-06 09:15:55 -05:00
Serhiy Storchaka 4d21297d28 gh-41779: Allow defining any __slots__ for a class derived from tuple (GH-141763) 2026-01-06 11:36:00 +02:00
Serhiy Storchaka 522563549a gh-143003: Fix possible shared buffer overflow in bytearray.extend() (GH-143086)
When __length_hint__() returns 0 for non-empty iterator, the data can be
written past the shared 0-terminated buffer, corrupting it.
2025-12-28 12:30:36 +00:00
Bénédikt Tran 61ee04834b gh-142557: fix UAF in bytearray.__mod__ when object is mutated while formatting %-style arguments (#143213) 2025-12-27 14:57:13 +00:00
Bénédikt Tran 84fcdbd86e gh-142664: fix PyObject_Hash invokation post GH-143217 (#143223) 2025-12-27 14:30:09 +00:00
Bénédikt Tran 00e24b80e0 gh-142664: fix UAF in memoryview.__hash__ via re-entrant data's __hash__ (#143217) 2025-12-27 13:12:03 +00:00
Bénédikt Tran 9976c2b634 gh-143195: fix UAF in {bytearray,memoryview}.hex(sep) via re-entrant sep.__len__ (#143209) 2025-12-27 13:32:52 +01:00
Yongtao Huang de22e718bb Remove redundant pycore_optimizer.h includes (#143184)
`pycore_optimizer.h` was included redundantly in
Objects/frameobject.c and Python/instrumentation.c.
Both includes are unnecessary and can be safely removed.
No functional change.

Signed-off-by: Yongtao Huang <yongtaoh2022@gmail.com>
2025-12-26 11:11:11 +00:00
Sam Gross 594a4631c3 gh-120321: Fix TSan reported races on gi_frame_state (gh-143128) 2025-12-24 16:10:43 -05:00
Sam Gross e8e044eda3 gh-143100: Fix memcpy data race in setobject.c (gh-143127) 2025-12-24 08:02:19 -05: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
Kumar Aditya 487e91c120 gh-129069: fix more thread safety issues in list (#143019) 2025-12-22 21:45:28 +05:30
Sam Gross 7607712b61 gh-120321: Avoid -Wunreachable-code warning on Clang (gh-143022) 2025-12-20 14:42:12 -05:00
Sam Gross e46f28c6af gh-129069: Fix listobject.c data races due to memmove (gh-142957)
The use of memmove and _Py_memory_repeat were not thread-safe in the
free threading build in some cases. In theory, memmove and
_Py_memory_repeat can copy byte-by-byte instead of pointer-by-pointer,
so concurrent readers could see uninitialized data or tearing.

Additionally, we should be using "release" (or stronger) ordering to be
compliant with the C11 memory model when copying objects within a list.
2025-12-19 18:06:47 -05:00
Sam Gross 4ea3c1a047 gh-120321: Fix TSan reported race in gen_clear_frame (gh-142995)
TSan treats compare-exchanges that fail as if they are writes
so there is a false positive with the read of gi_frame_state in
gen_close.
2025-12-19 17:33:49 -05: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
wangxiaolei 220f0b1077 gh-142560: prevent use-after-free in search-like methods by exporting buffer in bytearray (#142938) 2025-12-19 08:02:23 +00:00
Sam Gross f54d44d333 gh-129068: Make range iterators thread-safe (gh-142886)
Now that we specialize range iteration in the interpreter for the common
case where the iterator has only one reference, there's not a
significant performance cost to making the iteration thread-safe.
2025-12-18 13:11:51 -05:00
Kumar Aditya e22c49522b gh-142890: remove unnecessary interp parameter from dict functions and _PyDict_NotifyEvent (#142923) 2025-12-18 22:48:56 +05:30
Donghee Na 14f0b5191a gh-142419: Add mmap.set_name method for user custom annotation (gh-142480) 2025-12-18 23:33:49 +09:00
Sam Gross 25397f9541 gh-142766: Clear frame when generator.close() is called (gh-142838) 2025-12-17 13:06:32 -05:00
Bartosz Sławecki f277781bba gh-142737: Handle lost io.open in _Py_FindSourceFile (GH-142747) 2025-12-15 22:58:50 +00:00
Ken Jin 0ac4e6c6cd gh-134584: Remove custom float decref ops (GH-142576) 2025-12-15 19:38:58 +00:00
Sam Gross a882ae198a gh-142472: Clean-up _PyStackRef functions (gh-142479)
This combines most _PyStackRef functions and macros between the free
threaded and default builds.

- Remove Py_TAG_DEFERRED (same as Py_TAG_REFCNT)
- Remove PyStackRef_IsDeferred (same as !PyStackRef_RefcountOnObject)
2025-12-15 12:03:49 -05:00
Cody Maloney 14e6052b43 gh-139871: Optimize bytearray construction with encoding (#142243)
When a `str` is encoded in `bytearray.__init__` the encoder tends to
create a new unique bytes object. Rather than allocate new memory and
copy the bytes use the already created bytes object as bytearray
backing. The bigger the `str` the bigger the saving.

Mean +- std dev: [main_encoding] 497 us +- 9 us -> [encoding] 14.2 us +- 0.3 us: 34.97x faster

```python
import pyperf

runner = pyperf.Runner()

runner.timeit(
    name="encode",
    setup="a = 'a' * 1_000_000",
    stmt="bytearray(a, encoding='utf8')")
```
2025-12-15 13:10:31 +01:00
Neil Schemenauer 19c72d23fd gh-132657: Use stronger memory ordering for so->mask. (gh-142735)
We need to use release/acquire ordering for the 'mask' member of the set
structure. Without this, `set_lookkey_threadsafe()` could be looking at
the old value of `table` but the new value of `mask`.
2025-12-14 20:27:37 -08:00
Bénédikt Tran 4e4163676a gh-142554: avoid divmod crashes due to bad _pylong.int_divmod (#142673) 2025-12-14 09:38:23 +01:00
Neil Schemenauer c98182be8d gh-132657: Add lock-free set contains implementation (#132290)
This roughly follows what was done for dictobject to make a lock-free
lookup operation. With this change, the set contains operation scales much
better when used from multiple-threads. The frozenset contains performance
seems unchanged (as already lock-free).

Summary of changes:

* refactor set_lookkey() into set_do_lookup() which now takes a function
  pointer that does the entry comparison. This is similar to dictobject and
  do_lookup(). In an optimized build, the comparison function is inlined and
  there should be no performance cost to this.

* change set_do_lookup() to return a status separately from the entry value

* add set_compare_frozenset() and use if the object is a frozenset. For the
  free-threaded build, this avoids some overhead (locking, atomic operations,
  incref/decref on key)

* use FT_ATOMIC_* macros as needed for atomic loads and stores

* use a deferred free on the set table array, if shared (only on free-threaded
  build, normal build always does an immediate free)

* for free-threaded build, use explicit for loop to zero the table, rather than memcpy()

* when mutating the set, assign so->table to NULL while the change is a
  happening. Assign the real table array after the change is done.
2025-12-13 09:50:23 +00:00
Victor Stinner 7aa353c414 gh-142217: Deprecate the private _Py_Identifier C API (#142221)
Deprecate functions:

* _PyObject_CallMethodId()
* _PyObject_GetAttrId()
* _PyUnicode_FromId()
2025-12-12 14:10:25 +01:00
Sam Gross 0a62f8277e gh-142534: Avoid TSan warnings in dictobject.c (gh-142544)
There are places we use "relaxed" loads where C11 requires "consume" or
stronger. Unfortunately, compilers don't really implement "consume" so
fake it for our use in a way that avoids upsetting TSan.
2025-12-11 16:23:19 -05:00
Sam Gross a26c831bc4 gh-142589: Fix PyUnstable_Object_IsUniqueReferencedTemporary (gh-142593)
PyUnstable_Object_IsUniqueReferencedTemporary wasn't handling tagged
ints on the evaluation stack properly.
2025-12-11 14:41:03 -05:00
Dino Viehland da8199f884 gh-123241: Don't modify ref count during visitation (GH-142232) 2025-12-11 09:54:29 +01:00
AZero13 785268fdce gh-142433: Move deref to below the error when checking for laststring (#142402)
Move deref of laststring to below the error checking so the deref
is applied after the object in strings is replaced.
2025-12-10 16:41:52 +01:00
Donghee Na c4ccaf4b10 gh-141770: Annotate anonymous mmap usage if "-X dev" is used (gh-142079) 2025-12-08 14:47:19 +00:00
dr-carlos ff2577f56e gh-141732: Fix ExceptionGroup repr changing when original exception sequence is mutated (#141736) 2025-12-07 21:04:04 +00:00
Sam Gross 547d8daf78 gh-142218: Fix split table dictionary crash (gh-142229)
This fixes a regression introduced in gh-140558. The interpreter would
crash if we inserted a non `str` key into a split table that matches an
existing key.
2025-12-03 18:37:35 -05:00
Uwe L. Korn f6f456f950 gh-142038: Expand guard for types_world_is_stopped() to fix debug builds without assertions (#142039) 2025-12-03 15:24:17 +01:00
Victor Stinner 7e5fcae09b gh-142217: Remove internal _Py_Identifier functions (#142219)
Remove internal functions:

* _PyDict_ContainsId()
* _PyDict_DelItemId()
* _PyDict_GetItemIdWithError()
* _PyDict_SetItemId()
* _PyEval_GetBuiltinId()
* _PyObject_CallMethodIdNoArgs()
* _PyObject_CallMethodIdObjArgs()
* _PyObject_CallMethodIdOneArg()
* _PyObject_VectorcallMethodId()
* _PyUnicode_EqualToASCIIId()

These functions were not exported and so no usable outside CPython.
2025-12-03 14:33:32 +01:00
Petr Viktorin 226011ba12 gh-139165: Make Py_SIZE, Py_IS_TYPE,Py_ SET_SIZE regular functions in stable ABI (GH-139166)
* Make Py_{SIZE,IS_TYPE,SET_SIZE} regular functions in stable ABI

Group them together with Py_TYPE & Py_SET_TYPE to cut down
on repetitive preprocessor macros.
Format repetitive definitions in object.c more concisely.

Py_SET_TYPE is still left out of the Limited API.
2025-11-25 14:30:33 +01:00
Petr Viktorin bf66bce4ee gh-141780: Make PyModule_FromSlotsAndSpec enable GIL if needed (GH-141785) 2025-11-24 13:26:35 +01:00
Cody Maloney e265ce8a56 gh-139871: Optimize small takes in bytearray.take_bytes (GH-141741)
When less than half the buffer is taken just copy that small part out
rather than doing a big alloc + memmove + big shrink.
2025-11-20 08:49:05 +01:00
Serhiy Storchaka 4bcab461c2 gh-41779: Allow defining the __dict__ and __weakref__ __slots__ for any class (GH-141755) 2025-11-19 17:11:37 +00:00
Edward Xu ce79154176 gh-139103: fix free-threading dataclass.__init__ perf issue (gh-141596)
The dataclasses `__init__` function is generated dynamically by a call to `exec()` and so doesn't have deferred reference counting enabled. Enable deferred reference counting on functions when assigned as an attribute to type objects to avoid reference count contention when creating dataclass instances.
2025-11-19 00:57:59 +00:00
Victor Stinner 600f3feb23 gh-141070: Add PyUnstable_Object_Dump() function (#141072)
* Promote _PyObject_Dump() as a public function.
* Keep _PyObject_Dump() alias to PyUnstable_Object_Dump()
  for backward compatibility.
* Replace _PyObject_Dump() with PyUnstable_Object_Dump().

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
2025-11-18 16:13:13 +00:00
Sergey Miryanov 10bec7c1eb GH-141312: Allow only integers to longrangeiter_setstate state (GH-141317)
This fixes an assertion error when the new computed start is not an integer.
2025-11-14 14:52:01 +00:00
Victor Stinner 3bacae5598 gh-131510: Use PyUnstable_Unicode_GET_CACHED_HASH() (GH-141520)
Replace code that directly accesses PyASCIIObject.hash with
PyUnstable_Unicode_GET_CACHED_HASH().

Remove redundant "assert(PyUnicode_Check(op))" from
PyUnstable_Unicode_GET_CACHED_HASH(), _PyASCIIObject_CAST() already
implements the check.
2025-11-14 11:13:24 +01:00
Petr Viktorin a4dd66275b gh-140550: Use a bool for the Py_mod_gil value (GH-141519)
This needs a single bit, but was stored as a void* in the module
struct. This didn't matter due to packing, but now that there's
another bool in the struct, we can save a bit of memory by
making md_gil a bool.

Variables that changed type are renamed, to detect conflicts.
2025-11-14 10:38:49 +01: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