summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/objimpl.h53
-rw-r--r--Include/pymem.h51
-rw-r--r--Objects/object.c17
-rw-r--r--Objects/obmalloc.c42
4 files changed, 71 insertions, 92 deletions
diff --git a/Include/objimpl.h b/Include/objimpl.h
index 47e0da4..396c23b 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -57,43 +57,6 @@ Unless you have specific memory management requirements, it is
recommended to use PyObject_{New, NewVar, Del}. */
/*
- * Core object memory allocator
- * ============================
- */
-
-/* The purpose of the object allocator is to make the distinction
- between "object memory" and the rest within the Python heap.
-
- Object memory is the one allocated by PyObject_{New, NewVar}, i.e.
- the one that holds the object's representation defined by its C
- type structure, *excluding* any object-specific memory buffers that
- might be referenced by the structure (for type structures that have
- pointer fields). By default, the object memory allocator is
- implemented on top of the raw memory allocator.
-
- The PyCore_* macros can be defined to make the interpreter use a
- custom object memory allocator. They are reserved for internal
- memory management purposes exclusively. Both the core and extension
- modules should use the PyObject_* API. */
-
-#ifdef WITH_PYMALLOC
-void *_PyCore_ObjectMalloc(size_t nbytes);
-void *_PyCore_ObjectRealloc(void *p, size_t nbytes);
-void _PyCore_ObjectFree(void *p);
-#define PyCore_OBJECT_MALLOC _PyCore_ObjectMalloc
-#define PyCore_OBJECT_REALLOC _PyCore_ObjectRealloc
-#define PyCore_OBJECT_FREE _PyCore_ObjectFree
-#endif /* !WITH_PYMALLOC */
-
-#ifndef PyCore_OBJECT_MALLOC
-#undef PyCore_OBJECT_REALLOC
-#undef PyCore_OBJECT_FREE
-#define PyCore_OBJECT_MALLOC(n) PyCore_MALLOC(n)
-#define PyCore_OBJECT_REALLOC(p, n) PyCore_REALLOC((p), (n))
-#define PyCore_OBJECT_FREE(p) PyCore_FREE(p)
-#endif
-
-/*
* Raw object memory interface
* ===========================
*/
@@ -111,19 +74,19 @@ void _PyCore_ObjectFree(void *p);
/* Functions */
-/* Wrappers around PyCore_OBJECT_MALLOC and friends; useful if you
- need to be sure that you are using the same object memory allocator
- as Python. These wrappers *do not* make sure that allocating 0
- bytes returns a non-NULL pointer. Returned pointers must be checked
- for NULL explicitly; no action is performed on failure. */
+/* Wrappers that useful if you need to be sure that you are using the
+ same object memory allocator as Python. These wrappers *do not* make
+ sure that allocating 0 bytes returns a non-NULL pointer. Returned
+ pointers must be checked for NULL explicitly; no action is performed
+ on failure. */
extern DL_IMPORT(void *) PyObject_Malloc(size_t);
extern DL_IMPORT(void *) PyObject_Realloc(void *, size_t);
extern DL_IMPORT(void) PyObject_Free(void *);
/* Macros */
-#define PyObject_MALLOC(n) PyCore_OBJECT_MALLOC(n)
-#define PyObject_REALLOC(op, n) PyCore_OBJECT_REALLOC((void *)(op), (n))
-#define PyObject_FREE(op) PyCore_OBJECT_FREE((void *)(op))
+#define PyObject_MALLOC(n) _PyMalloc_MALLOC(n)
+#define PyObject_REALLOC(op, n) _PyMalloc_REALLOC((void *)(op), (n))
+#define PyObject_FREE(op) _PyMalloc_FREE((void *)(op))
/*
* Generic object allocator interface
diff --git a/Include/pymem.h b/Include/pymem.h
index a02a1e0..9592272 100644
--- a/Include/pymem.h
+++ b/Include/pymem.h
@@ -10,26 +10,6 @@
extern "C" {
#endif
-/*
- * Core memory allocator
- * =====================
- */
-
-/* To make sure the interpreter is user-malloc friendly, all memory
- APIs are implemented on top of this one.
-
- The PyCore_* macros can be defined to make the interpreter use a
- custom allocator. Note that they are for internal use only. Both
- the core and extension modules should use the PyMem_* API. */
-
-#ifndef PyCore_MALLOC
-#undef PyCore_REALLOC
-#undef PyCore_FREE
-#define PyCore_MALLOC(n) malloc(n)
-#define PyCore_REALLOC(p, n) realloc((p), (n))
-#define PyCore_FREE(p) free(p)
-#endif
-
/* BEWARE:
Each interface exports both functions and macros. Extension modules
@@ -51,9 +31,12 @@ extern "C" {
* ====================
*/
+/* To make sure the interpreter is user-malloc friendly, all memory
+ APIs are implemented on top of this one. */
+
/* Functions */
-/* Function wrappers around PyCore_MALLOC and friends; useful if you
+/* Function wrappers around PyMem_MALLOC and friends; useful if you
need to be sure that you are using the same memory allocator as
Python. Note that the wrappers make sure that allocating 0 bytes
returns a non-NULL pointer, even if the underlying malloc
@@ -66,10 +49,12 @@ extern DL_IMPORT(void) PyMem_Free(void *);
/* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are
no longer supported. They used to call PyErr_NoMemory() on failure. */
-/* Macros */
-#define PyMem_MALLOC(n) PyCore_MALLOC(n)
-#define PyMem_REALLOC(p, n) PyCore_REALLOC((void *)(p), (n))
-#define PyMem_FREE(p) PyCore_FREE((void *)(p))
+/* Macros (override these if you want to a different malloc */
+#ifndef PyMem_MALLOC
+#define PyMem_MALLOC(n) malloc(n)
+#define PyMem_REALLOC(p, n) realloc((void *)(p), (n))
+#define PyMem_FREE(p) free((void *)(p))
+#endif
/*
* Type-oriented memory interface
@@ -104,6 +89,22 @@ extern DL_IMPORT(void) PyMem_Free(void *);
it is recommended to write the test explicitly in the code.
Note that according to ANSI C, free(NULL) has no effect. */
+
+/* pymalloc (private to the interpreter) */
+#ifdef WITH_PYMALLOC
+void *_PyMalloc_Malloc(size_t nbytes);
+void *_PyMalloc_Realloc(void *p, size_t nbytes);
+void _PyMalloc_Free(void *p);
+#define _PyMalloc_MALLOC _PyMalloc_Malloc
+#define _PyMalloc_REALLOC _PyMalloc_Realloc
+#define _PyMalloc_FREE _PyMalloc_Free
+#else
+#define _PyMalloc_MALLOC PyMem_MALLOC
+#define _PyMalloc_REALLOC PyMem_REALLOC
+#define _PyMalloc_FREE PyMem_FREE
+#endif
+
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/object.c b/Objects/object.c
index 26ddd13..1602e89 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2093,4 +2093,19 @@ _PyTrash_destroy_chain(void)
#ifdef WITH_PYMALLOC
#include "obmalloc.c"
-#endif
+#else
+void *_PyMalloc_Malloc(size_t n)
+{
+ return PyMem_MALLOC(n);
+}
+
+void *_PyMalloc_Realloc(void *p, size_t n)
+{
+ return PyMem_REALLOC(p, n);
+}
+
+void _PyMalloc_Free(void *p)
+{
+ PyMem_FREE(p);
+}
+#endif /* !WITH_PYMALLOC */
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 57b1941..43149d5 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -349,7 +349,7 @@ static void (*free_hook)(void *) = NULL;
*/
void *
-_PyCore_ObjectMalloc(size_t nbytes)
+_PyMalloc_Malloc(size_t nbytes)
{
block *bp;
poolp pool;
@@ -479,7 +479,7 @@ _PyCore_ObjectMalloc(size_t nbytes)
* With malloc, we can't avoid loosing one page address space
* per arena due to the required alignment on page boundaries.
*/
- bp = (block *)PyCore_MALLOC(ARENA_SIZE + SYSTEM_PAGE_SIZE);
+ bp = (block *)PyMem_MALLOC(ARENA_SIZE + SYSTEM_PAGE_SIZE);
if (bp == NULL) {
UNLOCK();
goto redirect;
@@ -510,13 +510,13 @@ _PyCore_ObjectMalloc(size_t nbytes)
* last chance to serve the request) or when the max memory limit
* has been reached.
*/
- return (void *)PyCore_MALLOC(nbytes);
+ return (void *)PyMem_MALLOC(nbytes);
}
/* free */
void
-_PyCore_ObjectFree(void *p)
+_PyMalloc_Free(void *p)
{
poolp pool;
poolp next, prev;
@@ -536,7 +536,7 @@ _PyCore_ObjectFree(void *p)
offset = (off_t )p & POOL_SIZE_MASK;
pool = (poolp )((block *)p - offset);
if (pool->pooladdr != pool || pool->magic != (uint )POOL_MAGIC) {
- PyCore_FREE(p);
+ PyMem_FREE(p);
return;
}
@@ -595,7 +595,7 @@ _PyCore_ObjectFree(void *p)
/* realloc */
void *
-_PyCore_ObjectRealloc(void *p, size_t nbytes)
+_PyMalloc_Realloc(void *p, size_t nbytes)
{
block *bp;
poolp pool;
@@ -607,7 +607,7 @@ _PyCore_ObjectRealloc(void *p, size_t nbytes)
#endif
if (p == NULL)
- return _PyCore_ObjectMalloc(nbytes);
+ return _PyMalloc_Malloc(nbytes);
/* realloc(p, 0) on big blocks is redirected. */
pool = (poolp )((block *)p - ((off_t )p & POOL_SIZE_MASK));
@@ -618,7 +618,7 @@ _PyCore_ObjectRealloc(void *p, size_t nbytes)
size = nbytes;
goto malloc_copy_free;
}
- bp = (block *)PyCore_REALLOC(p, nbytes);
+ bp = (block *)PyMem_REALLOC(p, nbytes);
}
else {
/* We're in charge of this block */
@@ -627,7 +627,7 @@ _PyCore_ObjectRealloc(void *p, size_t nbytes)
/* Don't bother if a smaller size was requested
except for realloc(p, 0) == free(p), ret NULL */
if (nbytes == 0) {
- _PyCore_ObjectFree(p);
+ _PyMalloc_Free(p);
bp = NULL;
}
else
@@ -637,10 +637,10 @@ _PyCore_ObjectRealloc(void *p, size_t nbytes)
malloc_copy_free:
- bp = (block *)_PyCore_ObjectMalloc(nbytes);
+ bp = (block *)_PyMalloc_Malloc(nbytes);
if (bp != NULL) {
memcpy(bp, p, size);
- _PyCore_ObjectFree(p);
+ _PyMalloc_Free(p);
}
}
}
@@ -651,7 +651,7 @@ _PyCore_ObjectRealloc(void *p, size_t nbytes)
/* -- unused --
void *
-_PyCore_ObjectCalloc(size_t nbel, size_t elsz)
+_PyMalloc_Calloc(size_t nbel, size_t elsz)
{
void *p;
size_t nbytes;
@@ -662,7 +662,7 @@ _PyCore_ObjectCalloc(size_t nbel, size_t elsz)
#endif
nbytes = nbel * elsz;
- p = _PyCore_ObjectMalloc(nbytes);
+ p = _PyMalloc_Malloc(nbytes);
if (p != NULL)
memset(p, 0, nbytes);
return p;
@@ -678,10 +678,10 @@ _PyCore_ObjectCalloc(size_t nbel, size_t elsz)
#ifdef WITH_MALLOC_HOOKS
void
-_PyCore_ObjectMalloc_SetHooks( void *(*malloc_func)(size_t),
- void *(*calloc_func)(size_t, size_t),
- void *(*realloc_func)(void *, size_t),
- void (*free_func)(void *) )
+_PyMalloc_SetHooks( void *(*malloc_func)(size_t),
+ void *(*calloc_func)(size_t, size_t),
+ void *(*realloc_func)(void *, size_t),
+ void (*free_func)(void *) )
{
LOCK();
malloc_hook = malloc_func;
@@ -692,10 +692,10 @@ _PyCore_ObjectMalloc_SetHooks( void *(*malloc_func)(size_t),
}
void
-_PyCore_ObjectMalloc_FetchHooks( void *(**malloc_funcp)(size_t),
- void *(**calloc_funcp)(size_t, size_t),
- void *(**realloc_funcp)(void *, size_t),
- void (**free_funcp)(void *) )
+_PyMalloc_FetchHooks( void *(**malloc_funcp)(size_t),
+ void *(**calloc_funcp)(size_t, size_t),
+ void *(**realloc_funcp)(void *, size_t),
+ void (**free_funcp)(void *) )
{
LOCK();
*malloc_funcp = malloc_hook;