gh-115491: Keep some fields valid across allocations (free-threading) (#115573)

This avoids filling the memory occupied by ob_tid, ob_ref_local, and
ob_ref_shared with debug bytes (e.g., 0xDD) in mimalloc in the
free-threaded build.
This commit is contained in:
Sam Gross 2024-02-20 10:36:40 -05:00 committed by GitHub
parent c0b0c2f201
commit cc82e33af9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 25 deletions

View file

@ -2845,9 +2845,24 @@ tstate_mimalloc_bind(PyThreadState *tstate)
// pools to keep Python objects from different interpreters separate.
tld->segments.abandoned = &tstate->interp->mimalloc.abandoned_pool;
// Don't fill in the first N bytes up to ob_type in debug builds. We may
// access ob_tid and the refcount fields in the dict and list lock-less
// accesses, so they must remain valid for a while after deallocation.
size_t base_offset = offsetof(PyObject, ob_type);
if (_PyMem_DebugEnabled()) {
// The debug allocator adds two words at the beginning of each block.
base_offset += 2 * sizeof(size_t);
}
size_t debug_offsets[_Py_MIMALLOC_HEAP_COUNT] = {
[_Py_MIMALLOC_HEAP_OBJECT] = base_offset,
[_Py_MIMALLOC_HEAP_GC] = base_offset,
[_Py_MIMALLOC_HEAP_GC_PRE] = base_offset + 2 * sizeof(PyObject *),
};
// Initialize each heap
for (uint8_t i = 0; i < _Py_MIMALLOC_HEAP_COUNT; i++) {
_mi_heap_init_ex(&mts->heaps[i], tld, _mi_arena_id_none(), false, i);
mts->heaps[i].debug_offset = (uint8_t)debug_offsets[i];
}
// By default, object allocations use _Py_MIMALLOC_HEAP_OBJECT.