mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			170 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| /* Lowest-level memory allocation interface */
 | |
| 
 | |
| #ifndef Py_PYMEM_H
 | |
| #define Py_PYMEM_H
 | |
| 
 | |
| #include "pyport.h"
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| 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.
 | |
| 
 | |
|    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
 | |
| #undef PyCore_REALLOC
 | |
| #undef PyCore_FREE
 | |
| #define PyCore_MALLOC(n)        PyCore_MALLOC_FUNC(n)
 | |
| #define PyCore_REALLOC(p, n)    PyCore_REALLOC_FUNC((p), (n))
 | |
| #define PyCore_FREE(p)          PyCore_FREE_FUNC(p)
 | |
| #endif
 | |
| 
 | |
| /* BEWARE:
 | |
| 
 | |
|    Each interface exports both functions and macros. Extension modules
 | |
|    should normally use the functions for ensuring binary compatibility
 | |
|    of the user's code across Python versions. Subsequently, if the
 | |
|    Python runtime switches to its own malloc (different from standard
 | |
|    malloc), no recompilation is required for the extensions.
 | |
| 
 | |
|    The macro versions trade compatibility for speed. They can be used
 | |
|    whenever there is a performance problem, but their use implies
 | |
|    recompilation of the code for each new Python release. The Python
 | |
|    core uses the macros because it *is* compiled on every upgrade.
 | |
|    This might not be the case with 3rd party extensions in a custom
 | |
|    setup (for example, a customer does not always have access to the
 | |
|    source of 3rd party deliverables). You have been warned! */
 | |
| 
 | |
| /*
 | |
|  * Raw memory interface
 | |
|  * ====================
 | |
|  */
 | |
| 
 | |
| /* Functions */
 | |
| 
 | |
| /* Function wrappers around PyCore_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
 | |
|    doesn't. Returned pointers must be checked for NULL explicitly.
 | |
|    No action is performed on failure. */
 | |
| extern DL_IMPORT(void *) PyMem_Malloc(size_t);
 | |
| extern DL_IMPORT(void *) PyMem_Realloc(void *, size_t);
 | |
| 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))
 | |
| 
 | |
| /*
 | |
|  * Type-oriented memory interface
 | |
|  * ==============================
 | |
|  */
 | |
| 
 | |
| /* Functions */
 | |
| #define PyMem_New(type, n) \
 | |
| 	( (type *) PyMem_Malloc((n) * sizeof(type)) )
 | |
| #define PyMem_Resize(p, type, n) \
 | |
| 	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
 | |
| #define PyMem_Del(p) PyMem_Free(p)
 | |
| 
 | |
| /* Macros */
 | |
| #define PyMem_NEW(type, n) \
 | |
| 	( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
 | |
| #define PyMem_RESIZE(p, type, n) \
 | |
| 	if ((p) == NULL) \
 | |
| 		(p) = (type *)(PyMem_MALLOC( \
 | |
| 				    _PyMem_EXTRA + (n) * sizeof(type))); \
 | |
| 	else \
 | |
| 		(p) = (type *)(PyMem_REALLOC((p), \
 | |
| 				    _PyMem_EXTRA + (n) * sizeof(type)))
 | |
| #define PyMem_DEL(p) PyMem_FREE(p)
 | |
| 
 | |
| /* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
 | |
|    it is recommended to write the test explicitly in the code.
 | |
|    Note that according to ANSI C, free(NULL) has no effect. */
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #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 config.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 */
 | 
