Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f5c4b99

Browse files
committed
PyMem_Malloc() now uses the fast pymalloc allocator
Issue #26249: PyMem_Malloc() allocator family now uses the pymalloc allocator rather than system malloc(). Applications calling PyMem_Malloc() without holding the GIL can now crash: use PYTHONMALLOC=debug environment variable to validate the usage of memory allocators in your application.
1 parent 5439fc4 commit f5c4b99

5 files changed

Lines changed: 58 additions & 32 deletions

File tree

Doc/c-api/memory.rst

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,17 @@ The following function sets, modeled after the ANSI C standard, but specifying
165165
behavior when requesting zero bytes, are available for allocating and releasing
166166
memory from the Python heap.
167167
168-
The default memory block allocator uses the following functions:
169-
:c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`; call
170-
``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes.
168+
By default, these functions use :ref:`pymalloc memory allocator <pymalloc>`.
171169
172170
.. warning::
173171
174172
The :term:`GIL <global interpreter lock>` must be held when using these
175173
functions.
176174
175+
.. versionchanged:: 3.6
176+
177+
The default allocator is now pymalloc instead of system :c:func:`malloc`.
178+
177179
.. c:function:: void* PyMem_Malloc(size_t n)
178180
179181
Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
@@ -295,15 +297,32 @@ Customize Memory Allocators
295297
296298
Enum used to identify an allocator domain. Domains:
297299
298-
* :c:data:`PYMEM_DOMAIN_RAW`: functions :c:func:`PyMem_RawMalloc`,
299-
:c:func:`PyMem_RawRealloc`, :c:func:`PyMem_RawCalloc` and
300-
:c:func:`PyMem_RawFree`
301-
* :c:data:`PYMEM_DOMAIN_MEM`: functions :c:func:`PyMem_Malloc`,
302-
:c:func:`PyMem_Realloc`, :c:func:`PyMem_Calloc` and :c:func:`PyMem_Free`
303-
* :c:data:`PYMEM_DOMAIN_OBJ`: functions :c:func:`PyObject_Malloc`,
304-
:c:func:`PyObject_Realloc`, :c:func:`PyObject_Calloc` and
305-
:c:func:`PyObject_Free`
300+
.. c:var:: PYMEM_DOMAIN_RAW
301+
302+
Functions:
303+
304+
* :c:func:`PyMem_RawMalloc`
305+
* :c:func:`PyMem_RawRealloc`
306+
* :c:func:`PyMem_RawCalloc`
307+
* :c:func:`PyMem_RawFree`
308+
309+
.. c:var:: PYMEM_DOMAIN_MEM
306310
311+
Functions:
312+
313+
* :c:func:`PyMem_Malloc`,
314+
* :c:func:`PyMem_Realloc`
315+
* :c:func:`PyMem_Calloc`
316+
* :c:func:`PyMem_Free`
317+
318+
.. c:var:: PYMEM_DOMAIN_OBJ
319+
320+
Functions:
321+
322+
* :c:func:`PyObject_Malloc`
323+
* :c:func:`PyObject_Realloc`
324+
* :c:func:`PyObject_Calloc`
325+
* :c:func:`PyObject_Free`
307326
308327
.. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
309328
@@ -328,18 +347,12 @@ Customize Memory Allocators
328347
329348
.. c:function:: void PyMem_SetupDebugHooks(void)
330349
331-
Setup hooks to detect bugs in the following Python memory allocator
332-
functions:
333-
334-
- :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc`,
335-
:c:func:`PyMem_RawCalloc`, :c:func:`PyMem_RawFree`
336-
- :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc`, :c:func:`PyMem_Calloc`,
337-
:c:func:`PyMem_Free`
338-
- :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc`,
339-
:c:func:`PyObject_Calloc`, :c:func:`PyObject_Free`
350+
Setup hooks to detect bugs in the Python memory allocator functions.
340351
341352
Newly allocated memory is filled with the byte ``0xCB``, freed memory is
342-
filled with the byte ``0xDB``. Additional checks:
353+
filled with the byte ``0xDB``.
354+
355+
Runtime checks:
343356
344357
- Detect API violations, ex: :c:func:`PyObject_Free` called on a buffer
345358
allocated by :c:func:`PyMem_Malloc`
@@ -377,8 +390,9 @@ to 512 bytes) with a short lifetime. It uses memory mappings called "arenas"
377390
with a fixed size of 256 KB. It falls back to :c:func:`PyMem_RawMalloc` and
378391
:c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes.
379392
380-
*pymalloc* is the default allocator of the :c:data:`PYMEM_DOMAIN_OBJ` domain
381-
(ex: :c:func:`PyObject_Malloc`).
393+
*pymalloc* is the default allocator of the :c:data:`PYMEM_DOMAIN_MEM` (ex:
394+
:c:func:`PyObject_Malloc`) and :c:data:`PYMEM_DOMAIN_OBJ` (ex:
395+
:c:func:`PyObject_Malloc`) domains.
382396
383397
The arena allocator uses the following functions:
384398

Doc/using/cmdline.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,12 +628,11 @@ conflict.
628628
Set the family of memory allocators used by Python:
629629

630630
* ``malloc``: use the :c:func:`malloc` function of the C library
631-
for all Python memory allocators (ex: :c:func:`PyMem_RawMalloc`,
632-
:c:func:`PyMem_Malloc` and :c:func:`PyObject_Malloc`).
633-
* ``pymalloc``: :c:func:`PyObject_Malloc`, :c:func:`PyObject_Calloc` and
634-
:c:func:`PyObject_Realloc` use the :ref:`pymalloc allocator <pymalloc>`.
635-
Other Python memory allocators (ex: :c:func:`PyMem_RawMalloc` and
636-
:c:func:`PyMem_Malloc`) use :c:func:`malloc`.
631+
for all domains (:c:data:`PYMEM_DOMAIN_RAW`, :c:data:`PYMEM_DOMAIN_MEM`,
632+
:c:data:`PYMEM_DOMAIN_OBJ`).
633+
* ``pymalloc``: use the :ref:`pymalloc allocator <pymalloc>` for
634+
:c:data:`PYMEM_DOMAIN_MEM` and :c:data:`PYMEM_DOMAIN_OBJ` domains and use
635+
the :c:func:`malloc` function for the :c:data:`PYMEM_DOMAIN_RAW` domain.
637636

638637
Install debug hooks:
639638

Doc/whatsnew/3.6.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,5 +531,11 @@ Changes in the Python API
531531
Changes in the C API
532532
--------------------
533533

534+
* :c:func:`PyMem_Malloc` allocator family now uses the :ref:`pymalloc allocator
535+
<pymalloc>` rather than system :c:func:`malloc`. Applications calling
536+
:c:func:`PyMem_Malloc` without holding the GIL can now crash. Set the
537+
:envvar:`PYTHONMALLOC` environment variable to ``debug`` to validate the
538+
usage of memory allocators in your application. See :issue:`26249`.
539+
534540
* :c:func:`Py_Exit` (and the main interpreter) now override the exit status
535541
with 120 if flushing buffered data failed. See :issue:`5319`.

Misc/NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ Release date: tba
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #26249: Memory functions of the :c:func:`PyMem_Malloc` domain
14+
(:c:data:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc allocator <pymalloc>`
15+
rather than system :c:func:`malloc`. Applications calling
16+
:c:func:`PyMem_Malloc` without holding the GIL can now crash: use
17+
``PYTHONMALLOC=debug`` environment variable to validate the usage of memory
18+
allocators in your application.
19+
1320
- Issue #26802: Optimize function calls only using unpacking like
1421
``func(*tuple)`` (no other positional argument, no keyword): avoid copying
1522
the tuple. Patch written by Joe Jevnik.

Objects/obmalloc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ static PyMemAllocatorEx _PyMem_Raw = {
198198

199199
static PyMemAllocatorEx _PyMem = {
200200
#ifdef Py_DEBUG
201-
&_PyMem_Debug.mem, PYDBG_FUNCS
201+
&_PyMem_Debug.obj, PYDBG_FUNCS
202202
#else
203-
NULL, PYMEM_FUNCS
203+
NULL, PYOBJ_FUNCS
204204
#endif
205205
};
206206

@@ -256,7 +256,7 @@ _PyMem_SetupAllocators(const char *opt)
256256
PyMemAllocatorEx obj_alloc = {NULL, PYOBJ_FUNCS};
257257

258258
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &mem_alloc);
259-
PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &mem_alloc);
259+
PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &obj_alloc);
260260
PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &obj_alloc);
261261

262262
if (strcmp(opt, "pymalloc_debug") == 0)

0 commit comments

Comments
 (0)