Skip to content

Commit f772800

Browse files
committed
Fix free-list allocator mismatch for deopted JIT generators (ASAN root cause python#2)
Deopted JIT generators have their type changed from JitGen type to PyGen_Type during deopt. jitgen_dealloc then routed them to original_gen_dealloc which calls PyMem_RawFree. But the memory was allocated from JitGenFreeList's pool (operator new), not malloc. Fix: always use Cix_gen_dealloc_with_custom_free for ALL generators. It routes PyObject_GC_Del through Ci_free_jit_list_gen which checks fromThisArena() and returns pool-allocated generators to the free list instead of calling PyMem_RawFree.
1 parent f8564cc commit f772800

1 file changed

Lines changed: 10 additions & 14 deletions

File tree

Python/jit/generators_rt.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,19 @@ const destructor original_gen_dealloc = PyGen_Type.tp_dealloc;
3838
const destructor original_coro_dealloc = PyCoro_Type.tp_dealloc;
3939

4040
void jitgen_dealloc(PyObject* self) {
41-
// If this is NOT a JIT generator, use the original CPython dealloc.
42-
// JitGen_CheckAny returns false for regular PyGenObject/PyCoroObject
43-
// since their type differs from the JIT-specific gen/coro types.
44-
if (!JitGen_CheckAny(self)) {
45-
if (PyCoro_CheckExact(self)) {
46-
original_coro_dealloc(self);
47-
} else {
48-
original_gen_dealloc(self);
41+
// If this IS a JIT generator, deopt it first (closes the JIT frame).
42+
if (JitGen_CheckAny(self)) {
43+
if (!deopt_jit_gen(self)) {
44+
JIT_ABORT("Tried to dealloc a running JIT generator");
4945
}
50-
return;
51-
}
52-
53-
if (!deopt_jit_gen(self)) {
54-
JIT_ABORT("Tried to dealloc a running JIT generator");
5546
}
5647

57-
// CPython deallocation modified to respect our free-list.
48+
// Always use Cix_gen_dealloc_with_custom_free for ALL generators. This
49+
// routes PyObject_GC_Del through Ci_free_jit_list_gen which checks
50+
// fromThisArena() — returning free-list-allocated generators to the pool
51+
// instead of calling PyMem_RawFree. This is critical for deopted JIT
52+
// generators: deopt changes their type so JitGen_CheckAny returns false,
53+
// but they may still be allocated from the JitGenFreeList pool.
5854
Cix_gen_dealloc_with_custom_free(self);
5955
}
6056

0 commit comments

Comments
 (0)