mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Simpilify PyCore_* macros by assuming the function prototypes for
malloc() and free() don't change.
This commit is contained in:
parent
f6eafc3fe1
commit
11f5be8d88
3 changed files with 34 additions and 154 deletions
|
@ -77,40 +77,20 @@ recommended to use PyObject_{New, NewVar, Del}. */
|
||||||
modules should use the PyObject_* API. */
|
modules should use the PyObject_* API. */
|
||||||
|
|
||||||
#ifdef WITH_PYMALLOC
|
#ifdef WITH_PYMALLOC
|
||||||
#define PyCore_OBJECT_MALLOC_FUNC _PyCore_ObjectMalloc
|
void *_PyCore_ObjectMalloc(size_t nbytes);
|
||||||
#define PyCore_OBJECT_REALLOC_FUNC _PyCore_ObjectRealloc
|
void *_PyCore_ObjectRealloc(void *p, size_t nbytes);
|
||||||
#define PyCore_OBJECT_FREE_FUNC _PyCore_ObjectFree
|
void _PyCore_ObjectFree(void *p);
|
||||||
#define NEED_TO_DECLARE_OBJECT_MALLOC_AND_FRIEND
|
#define PyCore_OBJECT_MALLOC _PyCore_ObjectMalloc
|
||||||
|
#define PyCore_OBJECT_REALLOC _PyCore_ObjectRealloc
|
||||||
|
#define PyCore_OBJECT_FREE _PyCore_ObjectFree
|
||||||
#endif /* !WITH_PYMALLOC */
|
#endif /* !WITH_PYMALLOC */
|
||||||
|
|
||||||
#ifndef PyCore_OBJECT_MALLOC_FUNC
|
|
||||||
#undef PyCore_OBJECT_REALLOC_FUNC
|
|
||||||
#undef PyCore_OBJECT_FREE_FUNC
|
|
||||||
#define PyCore_OBJECT_MALLOC_FUNC PyCore_MALLOC_FUNC
|
|
||||||
#define PyCore_OBJECT_REALLOC_FUNC PyCore_REALLOC_FUNC
|
|
||||||
#define PyCore_OBJECT_FREE_FUNC PyCore_FREE_FUNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyCore_OBJECT_MALLOC_PROTO
|
|
||||||
#undef PyCore_OBJECT_REALLOC_PROTO
|
|
||||||
#undef PyCore_OBJECT_FREE_PROTO
|
|
||||||
#define PyCore_OBJECT_MALLOC_PROTO PyCore_MALLOC_PROTO
|
|
||||||
#define PyCore_OBJECT_REALLOC_PROTO PyCore_REALLOC_PROTO
|
|
||||||
#define PyCore_OBJECT_FREE_PROTO PyCore_FREE_PROTO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NEED_TO_DECLARE_OBJECT_MALLOC_AND_FRIEND
|
|
||||||
extern void *PyCore_OBJECT_MALLOC_FUNC PyCore_OBJECT_MALLOC_PROTO;
|
|
||||||
extern void *PyCore_OBJECT_REALLOC_FUNC PyCore_OBJECT_REALLOC_PROTO;
|
|
||||||
extern void PyCore_OBJECT_FREE_FUNC PyCore_OBJECT_FREE_PROTO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyCore_OBJECT_MALLOC
|
#ifndef PyCore_OBJECT_MALLOC
|
||||||
#undef PyCore_OBJECT_REALLOC
|
#undef PyCore_OBJECT_REALLOC
|
||||||
#undef PyCore_OBJECT_FREE
|
#undef PyCore_OBJECT_FREE
|
||||||
#define PyCore_OBJECT_MALLOC(n) PyCore_OBJECT_MALLOC_FUNC(n)
|
#define PyCore_OBJECT_MALLOC(n) PyCore_MALLOC(n)
|
||||||
#define PyCore_OBJECT_REALLOC(p, n) PyCore_OBJECT_REALLOC_FUNC((p), (n))
|
#define PyCore_OBJECT_REALLOC(p, n) PyCore_REALLOC((p), (n))
|
||||||
#define PyCore_OBJECT_FREE(p) PyCore_OBJECT_FREE_FUNC(p)
|
#define PyCore_OBJECT_FREE(p) PyCore_FREE(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -20,39 +20,14 @@ extern "C" {
|
||||||
|
|
||||||
The PyCore_* macros can be defined to make the interpreter use a
|
The PyCore_* macros can be defined to make the interpreter use a
|
||||||
custom allocator. Note that they are for internal use only. Both
|
custom allocator. Note that they are for internal use only. Both
|
||||||
the core and extension modules should use the PyMem_* API.
|
the core and extension modules should use the PyMem_* API. */
|
||||||
|
|
||||||
See the comment block at the end of this file for two scenarios
|
|
||||||
showing how to use this to use a different allocator. */
|
|
||||||
|
|
||||||
#ifndef PyCore_MALLOC_FUNC
|
|
||||||
#undef PyCore_REALLOC_FUNC
|
|
||||||
#undef PyCore_FREE_FUNC
|
|
||||||
#define PyCore_MALLOC_FUNC malloc
|
|
||||||
#define PyCore_REALLOC_FUNC realloc
|
|
||||||
#define PyCore_FREE_FUNC free
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyCore_MALLOC_PROTO
|
|
||||||
#undef PyCore_REALLOC_PROTO
|
|
||||||
#undef PyCore_FREE_PROTO
|
|
||||||
#define PyCore_MALLOC_PROTO (size_t)
|
|
||||||
#define PyCore_REALLOC_PROTO (void *, size_t)
|
|
||||||
#define PyCore_FREE_PROTO (void *)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NEED_TO_DECLARE_MALLOC_AND_FRIEND
|
|
||||||
extern void *PyCore_MALLOC_FUNC PyCore_MALLOC_PROTO;
|
|
||||||
extern void *PyCore_REALLOC_FUNC PyCore_REALLOC_PROTO;
|
|
||||||
extern void PyCore_FREE_FUNC PyCore_FREE_PROTO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyCore_MALLOC
|
#ifndef PyCore_MALLOC
|
||||||
#undef PyCore_REALLOC
|
#undef PyCore_REALLOC
|
||||||
#undef PyCore_FREE
|
#undef PyCore_FREE
|
||||||
#define PyCore_MALLOC(n) PyCore_MALLOC_FUNC(n)
|
#define PyCore_MALLOC(n) malloc(n)
|
||||||
#define PyCore_REALLOC(p, n) PyCore_REALLOC_FUNC((p), (n))
|
#define PyCore_REALLOC(p, n) realloc((p), (n))
|
||||||
#define PyCore_FREE(p) PyCore_FREE_FUNC(p)
|
#define PyCore_FREE(p) free(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BEWARE:
|
/* BEWARE:
|
||||||
|
@ -133,43 +108,4 @@ extern DL_IMPORT(void) PyMem_Free(void *);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SCENARIOS
|
|
||||||
|
|
||||||
Here are two scenarios by Vladimir Marangozov (the author of the
|
|
||||||
memory allocation redesign).
|
|
||||||
|
|
||||||
1) Scenario A
|
|
||||||
|
|
||||||
Suppose you want to use a debugging malloc library that collects info on
|
|
||||||
where the malloc calls originate from. Assume the interface is:
|
|
||||||
|
|
||||||
d_malloc(size_t n, char* src_file, unsigned long src_line) c.s.
|
|
||||||
|
|
||||||
In this case, you would define (for example in pyconfig.h) :
|
|
||||||
|
|
||||||
#define PyCore_MALLOC_FUNC d_malloc
|
|
||||||
...
|
|
||||||
#define PyCore_MALLOC_PROTO (size_t, char *, unsigned long)
|
|
||||||
...
|
|
||||||
#define NEED_TO_DECLARE_MALLOC_AND_FRIEND
|
|
||||||
|
|
||||||
#define PyCore_MALLOC(n) PyCore_MALLOC_FUNC((n), __FILE__, __LINE__)
|
|
||||||
...
|
|
||||||
|
|
||||||
2) Scenario B
|
|
||||||
|
|
||||||
Suppose you want to use malloc hooks (defined & initialized in a 3rd party
|
|
||||||
malloc library) instead of malloc functions. In this case, you would
|
|
||||||
define:
|
|
||||||
|
|
||||||
#define PyCore_MALLOC_FUNC (*malloc_hook)
|
|
||||||
...
|
|
||||||
#define NEED_TO_DECLARE_MALLOC_AND_FRIEND
|
|
||||||
|
|
||||||
and ignore the previous definitions about PyCore_MALLOC_FUNC, etc.
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !Py_PYMEM_H */
|
#endif /* !Py_PYMEM_H */
|
||||||
|
|
|
@ -53,42 +53,6 @@
|
||||||
|
|
||||||
/*==========================================================================*/
|
/*==========================================================================*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Public functions exported by this allocator.
|
|
||||||
*
|
|
||||||
* -- Define and use these names in your code to obtain or release memory --
|
|
||||||
*/
|
|
||||||
#define _THIS_MALLOC PyCore_OBJECT_MALLOC_FUNC
|
|
||||||
#define _THIS_CALLOC /* unused */
|
|
||||||
#define _THIS_REALLOC PyCore_OBJECT_REALLOC_FUNC
|
|
||||||
#define _THIS_FREE PyCore_OBJECT_FREE_FUNC
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Underlying allocator's functions called by this allocator.
|
|
||||||
* The underlying allocator is usually the one which comes with libc.
|
|
||||||
*
|
|
||||||
* -- Don't use these functions in your code (to avoid mixing allocators) --
|
|
||||||
*
|
|
||||||
* Redefine these __only__ if you are using a 3rd party general purpose
|
|
||||||
* allocator which exports functions with names _other_ than the standard
|
|
||||||
* malloc, calloc, realloc, free.
|
|
||||||
*/
|
|
||||||
#define _SYSTEM_MALLOC PyCore_MALLOC_FUNC
|
|
||||||
#define _SYSTEM_CALLOC /* unused */
|
|
||||||
#define _SYSTEM_REALLOC PyCore_REALLOC_FUNC
|
|
||||||
#define _SYSTEM_FREE PyCore_FREE_FUNC
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If malloc hooks are needed, names of the hooks' set & fetch
|
|
||||||
* functions exported by this allocator.
|
|
||||||
*/
|
|
||||||
#ifdef WITH_MALLOC_HOOKS
|
|
||||||
#define _SET_HOOKS _PyCore_ObjectMalloc_SetHooks
|
|
||||||
#define _FETCH_HOOKS _PyCore_ObjectMalloc_FetchHooks
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*==========================================================================*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocation strategy abstract:
|
* Allocation strategy abstract:
|
||||||
*
|
*
|
||||||
|
@ -385,7 +349,7 @@ static void (*free_hook)(void *) = NULL;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *
|
void *
|
||||||
_THIS_MALLOC(size_t nbytes)
|
_PyCore_ObjectMalloc(size_t nbytes)
|
||||||
{
|
{
|
||||||
block *bp;
|
block *bp;
|
||||||
poolp pool;
|
poolp pool;
|
||||||
|
@ -515,7 +479,7 @@ _THIS_MALLOC(size_t nbytes)
|
||||||
* With malloc, we can't avoid loosing one page address space
|
* With malloc, we can't avoid loosing one page address space
|
||||||
* per arena due to the required alignment on page boundaries.
|
* per arena due to the required alignment on page boundaries.
|
||||||
*/
|
*/
|
||||||
bp = (block *)_SYSTEM_MALLOC(ARENA_SIZE + SYSTEM_PAGE_SIZE);
|
bp = (block *)PyCore_MALLOC(ARENA_SIZE + SYSTEM_PAGE_SIZE);
|
||||||
if (bp == NULL) {
|
if (bp == NULL) {
|
||||||
UNLOCK();
|
UNLOCK();
|
||||||
goto redirect;
|
goto redirect;
|
||||||
|
@ -546,13 +510,13 @@ _THIS_MALLOC(size_t nbytes)
|
||||||
* last chance to serve the request) or when the max memory limit
|
* last chance to serve the request) or when the max memory limit
|
||||||
* has been reached.
|
* has been reached.
|
||||||
*/
|
*/
|
||||||
return (void *)_SYSTEM_MALLOC(nbytes);
|
return (void *)PyCore_MALLOC(nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free */
|
/* free */
|
||||||
|
|
||||||
void
|
void
|
||||||
_THIS_FREE(void *p)
|
_PyCore_ObjectFree(void *p)
|
||||||
{
|
{
|
||||||
poolp pool;
|
poolp pool;
|
||||||
poolp next, prev;
|
poolp next, prev;
|
||||||
|
@ -572,7 +536,7 @@ _THIS_FREE(void *p)
|
||||||
offset = (off_t )p & POOL_SIZE_MASK;
|
offset = (off_t )p & POOL_SIZE_MASK;
|
||||||
pool = (poolp )((block *)p - offset);
|
pool = (poolp )((block *)p - offset);
|
||||||
if (pool->pooladdr != pool || pool->magic != (uint )POOL_MAGIC) {
|
if (pool->pooladdr != pool || pool->magic != (uint )POOL_MAGIC) {
|
||||||
_SYSTEM_FREE(p);
|
PyCore_FREE(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +595,7 @@ _THIS_FREE(void *p)
|
||||||
/* realloc */
|
/* realloc */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
_THIS_REALLOC(void *p, size_t nbytes)
|
_PyCore_ObjectRealloc(void *p, size_t nbytes)
|
||||||
{
|
{
|
||||||
block *bp;
|
block *bp;
|
||||||
poolp pool;
|
poolp pool;
|
||||||
|
@ -643,7 +607,7 @@ _THIS_REALLOC(void *p, size_t nbytes)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return _THIS_MALLOC(nbytes);
|
return _PyCore_ObjectMalloc(nbytes);
|
||||||
|
|
||||||
/* realloc(p, 0) on big blocks is redirected. */
|
/* realloc(p, 0) on big blocks is redirected. */
|
||||||
pool = (poolp )((block *)p - ((off_t )p & POOL_SIZE_MASK));
|
pool = (poolp )((block *)p - ((off_t )p & POOL_SIZE_MASK));
|
||||||
|
@ -654,7 +618,7 @@ _THIS_REALLOC(void *p, size_t nbytes)
|
||||||
size = nbytes;
|
size = nbytes;
|
||||||
goto malloc_copy_free;
|
goto malloc_copy_free;
|
||||||
}
|
}
|
||||||
bp = (block *)_SYSTEM_REALLOC(p, nbytes);
|
bp = (block *)PyCore_REALLOC(p, nbytes);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* We're in charge of this block */
|
/* We're in charge of this block */
|
||||||
|
@ -663,7 +627,7 @@ _THIS_REALLOC(void *p, size_t nbytes)
|
||||||
/* Don't bother if a smaller size was requested
|
/* Don't bother if a smaller size was requested
|
||||||
except for realloc(p, 0) == free(p), ret NULL */
|
except for realloc(p, 0) == free(p), ret NULL */
|
||||||
if (nbytes == 0) {
|
if (nbytes == 0) {
|
||||||
_THIS_FREE(p);
|
_PyCore_ObjectFree(p);
|
||||||
bp = NULL;
|
bp = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -673,10 +637,10 @@ _THIS_REALLOC(void *p, size_t nbytes)
|
||||||
|
|
||||||
malloc_copy_free:
|
malloc_copy_free:
|
||||||
|
|
||||||
bp = (block *)_THIS_MALLOC(nbytes);
|
bp = (block *)_PyCore_ObjectMalloc(nbytes);
|
||||||
if (bp != NULL) {
|
if (bp != NULL) {
|
||||||
memcpy(bp, p, size);
|
memcpy(bp, p, size);
|
||||||
_THIS_FREE(p);
|
_PyCore_ObjectFree(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,7 +651,7 @@ _THIS_REALLOC(void *p, size_t nbytes)
|
||||||
|
|
||||||
/* -- unused --
|
/* -- unused --
|
||||||
void *
|
void *
|
||||||
_THIS_CALLOC(size_t nbel, size_t elsz)
|
_PyCore_ObjectCalloc(size_t nbel, size_t elsz)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
|
@ -698,7 +662,7 @@ _THIS_CALLOC(size_t nbel, size_t elsz)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nbytes = nbel * elsz;
|
nbytes = nbel * elsz;
|
||||||
p = _THIS_MALLOC(nbytes);
|
p = _PyCore_ObjectMalloc(nbytes);
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
memset(p, 0, nbytes);
|
memset(p, 0, nbytes);
|
||||||
return p;
|
return p;
|
||||||
|
@ -714,10 +678,10 @@ _THIS_CALLOC(size_t nbel, size_t elsz)
|
||||||
#ifdef WITH_MALLOC_HOOKS
|
#ifdef WITH_MALLOC_HOOKS
|
||||||
|
|
||||||
void
|
void
|
||||||
_SET_HOOKS( void *(*malloc_func)(size_t),
|
_PyCore_ObjectMalloc_SetHooks( void *(*malloc_func)(size_t),
|
||||||
void *(*calloc_func)(size_t, size_t),
|
void *(*calloc_func)(size_t, size_t),
|
||||||
void *(*realloc_func)(void *, size_t),
|
void *(*realloc_func)(void *, size_t),
|
||||||
void (*free_func)(void *) )
|
void (*free_func)(void *) )
|
||||||
{
|
{
|
||||||
LOCK();
|
LOCK();
|
||||||
malloc_hook = malloc_func;
|
malloc_hook = malloc_func;
|
||||||
|
@ -728,10 +692,10 @@ _SET_HOOKS( void *(*malloc_func)(size_t),
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_FETCH_HOOKS( void *(**malloc_funcp)(size_t),
|
_PyCore_ObjectMalloc_FetchHooks( void *(**malloc_funcp)(size_t),
|
||||||
void *(**calloc_funcp)(size_t, size_t),
|
void *(**calloc_funcp)(size_t, size_t),
|
||||||
void *(**realloc_funcp)(void *, size_t),
|
void *(**realloc_funcp)(void *, size_t),
|
||||||
void (**free_funcp)(void *) )
|
void (**free_funcp)(void *) )
|
||||||
{
|
{
|
||||||
LOCK();
|
LOCK();
|
||||||
*malloc_funcp = malloc_hook;
|
*malloc_funcp = malloc_hook;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue