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]

Reply via email to