17db96d56Sopenharmony_ci#ifndef Py_CPYTHON_PYMEM_H 27db96d56Sopenharmony_ci# error "this header file must not be included directly" 37db96d56Sopenharmony_ci#endif 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciPyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); 67db96d56Sopenharmony_ciPyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); 77db96d56Sopenharmony_ciPyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); 87db96d56Sopenharmony_ciPyAPI_FUNC(void) PyMem_RawFree(void *ptr); 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ 117db96d56Sopenharmony_ciPyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci/* strdup() using PyMem_RawMalloc() */ 147db96d56Sopenharmony_ciPyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci/* strdup() using PyMem_Malloc() */ 177db96d56Sopenharmony_ciPyAPI_FUNC(char *) _PyMem_Strdup(const char *str); 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci/* wcsdup() using PyMem_RawMalloc() */ 207db96d56Sopenharmony_ciPyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_citypedef enum { 247db96d56Sopenharmony_ci /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ 257db96d56Sopenharmony_ci PYMEM_DOMAIN_RAW, 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ 287db96d56Sopenharmony_ci PYMEM_DOMAIN_MEM, 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ 317db96d56Sopenharmony_ci PYMEM_DOMAIN_OBJ 327db96d56Sopenharmony_ci} PyMemAllocatorDomain; 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_citypedef enum { 357db96d56Sopenharmony_ci PYMEM_ALLOCATOR_NOT_SET = 0, 367db96d56Sopenharmony_ci PYMEM_ALLOCATOR_DEFAULT = 1, 377db96d56Sopenharmony_ci PYMEM_ALLOCATOR_DEBUG = 2, 387db96d56Sopenharmony_ci PYMEM_ALLOCATOR_MALLOC = 3, 397db96d56Sopenharmony_ci PYMEM_ALLOCATOR_MALLOC_DEBUG = 4, 407db96d56Sopenharmony_ci#ifdef WITH_PYMALLOC 417db96d56Sopenharmony_ci PYMEM_ALLOCATOR_PYMALLOC = 5, 427db96d56Sopenharmony_ci PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6, 437db96d56Sopenharmony_ci#endif 447db96d56Sopenharmony_ci} PyMemAllocatorName; 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_citypedef struct { 487db96d56Sopenharmony_ci /* user context passed as the first argument to the 4 functions */ 497db96d56Sopenharmony_ci void *ctx; 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci /* allocate a memory block */ 527db96d56Sopenharmony_ci void* (*malloc) (void *ctx, size_t size); 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci /* allocate a memory block initialized by zeros */ 557db96d56Sopenharmony_ci void* (*calloc) (void *ctx, size_t nelem, size_t elsize); 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci /* allocate or resize a memory block */ 587db96d56Sopenharmony_ci void* (*realloc) (void *ctx, void *ptr, size_t new_size); 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci /* release a memory block */ 617db96d56Sopenharmony_ci void (*free) (void *ctx, void *ptr); 627db96d56Sopenharmony_ci} PyMemAllocatorEx; 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci/* Get the memory block allocator of the specified domain. */ 657db96d56Sopenharmony_ciPyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, 667db96d56Sopenharmony_ci PyMemAllocatorEx *allocator); 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci/* Set the memory block allocator of the specified domain. 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci The new allocator must return a distinct non-NULL pointer when requesting 717db96d56Sopenharmony_ci zero bytes. 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL 747db96d56Sopenharmony_ci is not held when the allocator is called. 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci If the new allocator is not a hook (don't call the previous allocator), the 777db96d56Sopenharmony_ci PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks 787db96d56Sopenharmony_ci on top on the new allocator. */ 797db96d56Sopenharmony_ciPyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, 807db96d56Sopenharmony_ci PyMemAllocatorEx *allocator); 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci/* Setup hooks to detect bugs in the following Python memory allocator 837db96d56Sopenharmony_ci functions: 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() 867db96d56Sopenharmony_ci - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() 877db96d56Sopenharmony_ci - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci Newly allocated memory is filled with the byte 0xCB, freed memory is filled 907db96d56Sopenharmony_ci with the byte 0xDB. Additional checks: 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci - detect API violations, ex: PyObject_Free() called on a buffer allocated 937db96d56Sopenharmony_ci by PyMem_Malloc() 947db96d56Sopenharmony_ci - detect write before the start of the buffer (buffer underflow) 957db96d56Sopenharmony_ci - detect write after the end of the buffer (buffer overflow) 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci The function does nothing if Python is not compiled is debug mode. */ 987db96d56Sopenharmony_ciPyAPI_FUNC(void) PyMem_SetupDebugHooks(void); 99