123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /* The PyMem_ family: low-level memory allocation interfaces.
- See objimpl.h for the PyObject_ memory family.
- */
- #ifndef Py_PYMEM_H
- #define Py_PYMEM_H
- #include "pyport.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* BEWARE:
- Each interface exports both functions and macros. Extension modules should
- use the functions, to ensure binary compatibility across Python versions.
- Because the Python implementation is free to change internal details, and
- the macros may (or may not) expose details for speed, if you do use the
- macros you must recompile your extensions with each Python release.
- Never mix calls to PyMem_ with calls to the platform malloc/realloc/
- calloc/free. For example, on Windows different DLLs may end up using
- different heaps, and if you use PyMem_Malloc you'll get the memory from the
- heap used by the Python DLL; it could be a disaster if you free()'ed that
- directly in your own extension. Using PyMem_Free instead ensures Python
- can return the memory to the proper heap. As another example, in
- PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_
- memory functions in special debugging wrappers that add additional
- debugging info to dynamic memory blocks. The system routines have no idea
- what to do with that stuff, and the Python wrappers have no idea what to do
- with raw blocks obtained directly by the system routines then.
- The GIL must be held when using these APIs.
- */
- /*
- * Raw memory interface
- * ====================
- */
- /* Functions
- Functions supplying platform-independent semantics for malloc/realloc/
- free. These functions make sure that allocating 0 bytes returns a distinct
- non-NULL pointer (whenever possible -- if we're flat out of memory, NULL
- may be returned), even if the platform malloc and realloc don't.
- Returned pointers must be checked for NULL explicitly. No action is
- performed on failure (no exception is set, no warning is printed, etc).
- */
- PyAPI_FUNC(void *) PyMem_Malloc(size_t size);
- PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
- PyAPI_FUNC(void) PyMem_Free(void *ptr);
- /* Macros. */
- /* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
- for malloc(0), which would be treated as an error. Some platforms
- would return a pointer with no memory behind it, which would break
- pymalloc. To solve these problems, allocate an extra byte. */
- /* Returns NULL to indicate error if a negative size or size larger than
- Py_ssize_t can represent is supplied. Helps prevents security holes. */
- #define PyMem_MALLOC(n) PyMem_Malloc(n)
- #define PyMem_REALLOC(p, n) PyMem_Realloc(p, n)
- #define PyMem_FREE(p) PyMem_Free(p)
- /*
- * Type-oriented memory interface
- * ==============================
- *
- * Allocate memory for n objects of the given type. Returns a new pointer
- * or NULL if the request was too large or memory allocation failed. Use
- * these macros rather than doing the multiplication yourself so that proper
- * overflow checking is always done.
- */
- #define PyMem_New(type, n) \
- ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
- ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
- #define PyMem_NEW(type, n) \
- ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
- ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
- /*
- * The value of (p) is always clobbered by this macro regardless of success.
- * The caller MUST check if (p) is NULL afterwards and deal with the memory
- * error if so. This means the original value of (p) MUST be saved for the
- * caller's memory error handler to not lose track of it.
- */
- #define PyMem_Resize(p, type, n) \
- ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
- (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
- #define PyMem_RESIZE(p, type, n) \
- ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
- (type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
- /* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used
- * anymore. They're just confusing aliases for PyMem_{Free,FREE} now.
- */
- #define PyMem_Del PyMem_Free
- #define PyMem_DEL PyMem_FREE
- /* bpo-35053: expose _Py_tracemalloc_config for performance:
- _Py_NewReference() needs an efficient check to test if tracemalloc is
- tracing.
- It has to be defined in pymem.h, before object.h is included. */
- struct _PyTraceMalloc_Config {
- /* Module initialized?
- Variable protected by the GIL */
- enum {
- TRACEMALLOC_NOT_INITIALIZED,
- TRACEMALLOC_INITIALIZED,
- TRACEMALLOC_FINALIZED
- } initialized;
- /* Is tracemalloc tracing memory allocations?
- Variable protected by the GIL */
- int tracing;
- /* limit of the number of frames in a traceback, 1 by default.
- Variable protected by the GIL. */
- int max_nframe;
- /* use domain in trace key?
- Variable protected by the GIL. */
- int use_domain;
- };
- PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;
- #define _PyTraceMalloc_Config_INIT \
- {.initialized = TRACEMALLOC_NOT_INITIALIZED, \
- .tracing = 0, \
- .max_nframe = 1, \
- .use_domain = 0}
- #ifndef Py_LIMITED_API
- # define Py_CPYTHON_PYMEM_H
- # include "cpython/pymem.h"
- # undef Py_CPYTHON_PYMEM_H
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif /* !Py_PYMEM_H */
|