https://github.com/python/cpython/commit/836f2c97f99925e84ec20d3c6da335a841f63b62
commit: 836f2c97f99925e84ec20d3c6da335a841f63b62
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-02-18T04:16:27Z
summary:
gh-144914: use `mimalloc` for raw allocations on free-threading (#144916)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst
M Doc/whatsnew/3.15.rst
M Include/internal/pycore_pymem_init.h
M Objects/obmalloc.c
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index e5714765208ff6..62ce7121424651 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -1204,6 +1204,11 @@ Optimizations
(Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
Special thanks to the MSVC team including Hulon Jenkins.)
+* ``mimalloc`` is now used as the default allocator for
+ for raw memory allocations such as via :c:func:`PyMem_RawMalloc`
+ for better performance on :term:`free-threaded builds <free-threaded build>`.
+ (Contributed by Kumar Aditya in :gh:`144914`.)
+
base64 & binascii
-----------------
diff --git a/Include/internal/pycore_pymem_init.h
b/Include/internal/pycore_pymem_init.h
index c593edc86d9952..2a0e0817dcc7f8 100644
--- a/Include/internal/pycore_pymem_init.h
+++ b/Include/internal/pycore_pymem_init.h
@@ -30,6 +30,12 @@ extern void* _PyMem_MiCalloc(void *, size_t, size_t);
extern void _PyMem_MiFree(void *, void *);
extern void* _PyMem_MiRealloc(void *, void *, size_t);
# define PYMEM_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc,
_PyMem_MiRealloc, _PyMem_MiFree}
+extern void* _PyMem_MiRawMalloc(void *, size_t);
+extern void* _PyMem_MiRawCalloc(void *, size_t, size_t);
+extern void _PyMem_MiRawFree(void *, void *);
+extern void* _PyMem_MiRawRealloc(void *, void *, size_t);
+# undef PYRAW_ALLOC
+# define PYRAW_ALLOC {NULL, _PyMem_MiRawMalloc, _PyMem_MiRawCalloc,
_PyMem_MiRawRealloc, _PyMem_MiRawFree}
#elif defined(WITH_PYMALLOC)
extern void* _PyObject_Malloc(void *, size_t);
extern void* _PyObject_Calloc(void *, size_t, size_t);
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst
new file mode 100644
index 00000000000000..f13b8541a0ebe2
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst
@@ -0,0 +1 @@
+Use ``mimalloc`` for raw memory allocations such as via
:c:func:`PyMem_RawMalloc` for better performance on :term:`free-threaded builds
<free-threaded build>`. Patch by Kumar Aditya.
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index ce2e39790bd76c..b59ebdfbda3897 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -358,6 +358,29 @@ _PyObject_MiFree(void *ctx, void *ptr)
mi_free(ptr);
}
+void *
+_PyMem_MiRawMalloc(void *ctx, size_t size)
+{
+ return mi_malloc(size);
+}
+
+void *
+_PyMem_MiRawCalloc(void *ctx, size_t nelem, size_t elsize)
+{
+ return mi_calloc(nelem, elsize);
+}
+
+void *
+_PyMem_MiRawRealloc(void *ctx, void *ptr, size_t size)
+{
+ return mi_realloc(ptr, size);
+}
+
+void
+_PyMem_MiRawFree(void *ctx, void *ptr)
+{
+ mi_free(ptr);
+}
#endif // WITH_MIMALLOC
@@ -365,7 +388,8 @@ _PyObject_MiFree(void *ctx, void *ptr)
#ifdef WITH_MIMALLOC
-# define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc,
_PyMem_MiRealloc, _PyMem_MiFree}
+# define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc,
_PyMem_MiRealloc, _PyMem_MiFree}
+# define MIMALLOC_RAWALLOC {NULL, _PyMem_MiRawMalloc, _PyMem_MiRawCalloc,
_PyMem_MiRawRealloc, _PyMem_MiRawFree}
# define MIMALLOC_OBJALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc,
_PyObject_MiRealloc, _PyObject_MiFree}
#endif
@@ -383,7 +407,7 @@ void* _PyObject_Realloc(void *ctx, void *ptr, size_t size);
#if defined(Py_GIL_DISABLED)
// Py_GIL_DISABLED requires using mimalloc for "mem" and "obj" domains.
-# define PYRAW_ALLOC MALLOC_ALLOC
+# define PYRAW_ALLOC MIMALLOC_RAWALLOC
# define PYMEM_ALLOC MIMALLOC_ALLOC
# define PYOBJ_ALLOC MIMALLOC_OBJALLOC
#elif defined(WITH_PYMALLOC)
@@ -758,7 +782,7 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
case PYMEM_ALLOCATOR_MIMALLOC:
case PYMEM_ALLOCATOR_MIMALLOC_DEBUG:
{
- PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC;
+ PyMemAllocatorEx malloc_alloc = MIMALLOC_RAWALLOC;
set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc);
PyMemAllocatorEx pymalloc = MIMALLOC_ALLOC;
@@ -828,6 +852,7 @@ get_current_allocator_name_unlocked(void)
#ifdef WITH_MIMALLOC
PyMemAllocatorEx mimalloc = MIMALLOC_ALLOC;
PyMemAllocatorEx mimalloc_obj = MIMALLOC_OBJALLOC;
+ PyMemAllocatorEx mimalloc_raw = MIMALLOC_RAWALLOC;
#endif
if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) &&
@@ -845,7 +870,7 @@ get_current_allocator_name_unlocked(void)
}
#endif
#ifdef WITH_MIMALLOC
- if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) &&
+ if (pymemallocator_eq(&_PyMem_Raw, &mimalloc_raw) &&
pymemallocator_eq(&_PyMem, &mimalloc) &&
pymemallocator_eq(&_PyObject, &mimalloc_obj))
{
@@ -877,7 +902,7 @@ get_current_allocator_name_unlocked(void)
}
#endif
#ifdef WITH_MIMALLOC
- if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) &&
+ if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &mimalloc_raw) &&
pymemallocator_eq(&_PyMem_Debug.mem.alloc, &mimalloc) &&
pymemallocator_eq(&_PyMem_Debug.obj.alloc, &mimalloc_obj))
{
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]