]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-144914: use `mimalloc` for raw allocations on free-threading (#144916)
authorKumar Aditya <kumaraditya@python.org>
Wed, 18 Feb 2026 04:16:27 +0000 (09:46 +0530)
committerGitHub <noreply@github.com>
Wed, 18 Feb 2026 04:16:27 +0000 (04:16 +0000)
Doc/whatsnew/3.15.rst
Include/internal/pycore_pymem_init.h
Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst [new file with mode: 0644]
Objects/obmalloc.c

index e5714765208ff6393029caac793b836ebe4f31d4..62ce7121424651029389eccaa7a8efccec2e25ce 100644 (file)
@@ -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
 -----------------
index c593edc86d9952aa9b001006122460ee6f215c44..2a0e0817dcc7f86dabfa236787477372f2f7bc9a 100644 (file)
@@ -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 (file)
index 0000000..f13b854
--- /dev/null
@@ -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.
index ce2e39790bd76cdaa7f0f9372781bd2b68623e81..b59ebdfbda389773e9b6c50b5177cdb87776f3d6 100644 (file)
@@ -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))
         {