From 6cf185dc064577c6f472c86741e91fb28ec82e2d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2013 15:58:42 +0200 Subject: [PATCH] Issue #18874: _PyObject_Malloc/Realloc/Free() now falls back on _PyMem_RawMalloc/Realloc/Free, instead of _PyMem_Malloc/Realloc/Free. So it becomes possible to use the fast pymalloc allocator for the PYMEM_DOMAIN_MEM domain (PyMem_Malloc/Realloc/Free functions). --- Doc/c-api/memory.rst | 4 ++-- Objects/obmalloc.c | 36 +++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index e4a759b5634..a82e1c2f2c5 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -288,8 +288,8 @@ Customize PyObject Arena Allocator Python has a *pymalloc* allocator for allocations smaller than 512 bytes. This allocator is optimized for small objects with a short lifetime. It uses memory mappings called "arenas" with a fixed size of 256 KB. It falls back to -:c:func:`PyMem_Malloc` and :c:func:`PyMem_Realloc` for allocations larger than -512 bytes. *pymalloc* is the default allocator used by +:c:func:`PyMem_RawMalloc` and :c:func:`PyMem_RawRealloc` for allocations larger +than 512 bytes. *pymalloc* is the default allocator used by :c:func:`PyObject_Malloc`. The default arena allocator uses the following functions: diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index f7b3e491ca4..004cfaac617 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -125,10 +125,11 @@ _PyObject_ArenaFree(void *ctx, void *ptr, size_t size) #define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawRealloc, _PyMem_RawFree #ifdef WITH_PYMALLOC -#define PYOBJECT_FUNCS _PyObject_Malloc, _PyObject_Realloc, _PyObject_Free +# define PYOBJ_FUNCS _PyObject_Malloc, _PyObject_Realloc, _PyObject_Free #else -#define PYOBJECT_FUNCS PYRAW_FUNCS +# define PYOBJ_FUNCS PYRAW_FUNCS #endif +#define PYMEM_FUNCS PYRAW_FUNCS #ifdef PYMALLOC_DEBUG typedef struct { @@ -142,16 +143,16 @@ static struct { debug_alloc_api_t obj; } _PyMem_Debug = { {'r', {NULL, PYRAW_FUNCS}}, - {'m', {NULL, PYRAW_FUNCS}}, - {'o', {NULL, PYOBJECT_FUNCS}} + {'m', {NULL, PYMEM_FUNCS}}, + {'o', {NULL, PYOBJ_FUNCS}} }; -#define PYDEBUG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugRealloc, _PyMem_DebugFree +#define PYDBG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugRealloc, _PyMem_DebugFree #endif static PyMemAllocator _PyMem_Raw = { #ifdef PYMALLOC_DEBUG - &_PyMem_Debug.raw, PYDEBUG_FUNCS + &_PyMem_Debug.raw, PYDBG_FUNCS #else NULL, PYRAW_FUNCS #endif @@ -159,23 +160,24 @@ static PyMemAllocator _PyMem_Raw = { static PyMemAllocator _PyMem = { #ifdef PYMALLOC_DEBUG - &_PyMem_Debug.mem, PYDEBUG_FUNCS + &_PyMem_Debug.mem, PYDBG_FUNCS #else - NULL, PYRAW_FUNCS + NULL, PYMEM_FUNCS #endif }; static PyMemAllocator _PyObject = { #ifdef PYMALLOC_DEBUG - &_PyMem_Debug.obj, PYDEBUG_FUNCS + &_PyMem_Debug.obj, PYDBG_FUNCS #else - NULL, PYOBJECT_FUNCS + NULL, PYOBJ_FUNCS #endif }; #undef PYRAW_FUNCS -#undef PYOBJECT_FUNCS -#undef PYDEBUG_FUNCS +#undef PYMEM_FUNCS +#undef PYOBJ_FUNCS +#undef PYDBG_FUNCS static PyObjectArenaAllocator _PyObject_Arena = {NULL, #ifdef MS_WINDOWS @@ -924,7 +926,7 @@ new_arena(void) return NULL; /* overflow */ #endif nbytes = numarenas * sizeof(*arenas); - arenaobj = (struct arena_object *)PyMem_Realloc(arenas, nbytes); + arenaobj = (struct arena_object *)PyMem_RawRealloc(arenas, nbytes); if (arenaobj == NULL) return NULL; arenas = arenaobj; @@ -1309,7 +1311,7 @@ redirect: * has been reached. */ { - void *result = PyMem_Malloc(nbytes); + void *result = PyMem_RawMalloc(nbytes); if (!result) _Py_AllocatedBlocks--; return result; @@ -1539,7 +1541,7 @@ _PyObject_Free(void *ctx, void *p) redirect: #endif /* We didn't allocate this address. */ - PyMem_Free(p); + PyMem_RawFree(p); } /* realloc. If p is NULL, this acts like malloc(nbytes). Else if nbytes==0, @@ -1608,14 +1610,14 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes) * at p. Instead we punt: let C continue to manage this block. */ if (nbytes) - return PyMem_Realloc(p, nbytes); + return PyMem_RawRealloc(p, nbytes); /* C doesn't define the result of realloc(p, 0) (it may or may not * return NULL then), but Python's docs promise that nbytes==0 never * returns NULL. We don't pass 0 to realloc(), to avoid that endcase * to begin with. Even then, we can't be sure that realloc() won't * return NULL. */ - bp = PyMem_Realloc(p, 1); + bp = PyMem_RawRealloc(p, 1); return bp ? bp : p; }