| 
									
										
										
										
											2019-05-24 17:01:38 +02:00
										 |  |  | #ifndef Py_INTERNAL_PYMEM_H
 | 
					
						
							|  |  |  | #define Py_INTERNAL_PYMEM_H
 | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 23:02:26 +02:00
										 |  |  | #ifndef Py_BUILD_CORE
 | 
					
						
							|  |  |  | #  error "this header requires Py_BUILD_CORE define"
 | 
					
						
							| 
									
										
										
										
											2018-10-31 20:19:24 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 11:38:42 +02:00
										 |  |  | #include "pymem.h"      // PyMemAllocatorName
 | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-31 20:19:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Set the memory allocator of the specified domain to the default.
 | 
					
						
							|  |  |  |    Save the old allocator into *old_alloc if it's non-NULL. | 
					
						
							|  |  |  |    Return on success, or return -1 if the domain is unknown. */ | 
					
						
							|  |  |  | PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( | 
					
						
							|  |  |  |     PyMemAllocatorDomain domain, | 
					
						
							|  |  |  |     PyMemAllocatorEx *old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-07 22:31:42 +02:00
										 |  |  | /* Special bytes broadcast into debug memory blocks at appropriate times.
 | 
					
						
							|  |  |  |    Strings of these are unlikely to be valid addresses, floats, ints or | 
					
						
							|  |  |  |    7-bit ASCII. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - PYMEM_CLEANBYTE: clean (newly allocated) memory | 
					
						
							|  |  |  |    - PYMEM_DEADBYTE dead (newly freed) memory | 
					
						
							|  |  |  |    - PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 09:32:13 +02:00
										 |  |  |    Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and | 
					
						
							| 
									
										
										
										
											2019-10-07 22:31:42 +02:00
										 |  |  |    0xFD to use the same values than Windows CRT debug malloc() and free(). | 
					
						
							|  |  |  |    If modified, _PyMem_IsPtrFreed() should be updated as well. */ | 
					
						
							|  |  |  | #define PYMEM_CLEANBYTE      0xCD
 | 
					
						
							|  |  |  | #define PYMEM_DEADBYTE       0xDD
 | 
					
						
							|  |  |  | #define PYMEM_FORBIDDENBYTE  0xFD
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 11:33:27 +02:00
										 |  |  | /* Heuristic checking if a pointer value is newly allocated
 | 
					
						
							| 
									
										
										
										
											2019-10-07 18:42:01 +02:00
										 |  |  |    (uninitialized), newly freed or NULL (is equal to zero). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The pointer is not dereferenced, only the pointer value is checked. | 
					
						
							| 
									
										
										
										
											2019-04-11 11:33:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |    The heuristic relies on the debug hooks on Python memory allocators which | 
					
						
							| 
									
										
										
										
											2019-04-11 13:01:15 +02:00
										 |  |  |    fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory | 
					
						
							|  |  |  |    with DEADBYTE (0xDD). Detect also "untouchable bytes" marked | 
					
						
							|  |  |  |    with FORBIDDENBYTE (0xFD). */ | 
					
						
							| 
									
										
										
										
											2021-07-15 16:36:51 -07:00
										 |  |  | static inline int _PyMem_IsPtrFreed(const void *ptr) | 
					
						
							| 
									
										
										
										
											2019-04-11 11:33:27 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     uintptr_t value = (uintptr_t)ptr; | 
					
						
							|  |  |  | #if SIZEOF_VOID_P == 8
 | 
					
						
							| 
									
										
										
										
											2019-10-07 18:42:01 +02:00
										 |  |  |     return (value == 0 | 
					
						
							|  |  |  |             || value == (uintptr_t)0xCDCDCDCDCDCDCDCD | 
					
						
							| 
									
										
										
										
											2019-04-11 13:01:15 +02:00
										 |  |  |             || value == (uintptr_t)0xDDDDDDDDDDDDDDDD | 
					
						
							|  |  |  |             || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); | 
					
						
							| 
									
										
										
										
											2019-04-11 11:33:27 +02:00
										 |  |  | #elif SIZEOF_VOID_P == 4
 | 
					
						
							| 
									
										
										
										
											2019-10-07 18:42:01 +02:00
										 |  |  |     return (value == 0 | 
					
						
							|  |  |  |             || value == (uintptr_t)0xCDCDCDCD | 
					
						
							| 
									
										
										
										
											2019-04-11 13:01:15 +02:00
										 |  |  |             || value == (uintptr_t)0xDDDDDDDD | 
					
						
							|  |  |  |             || value == (uintptr_t)0xFDFDFDFD); | 
					
						
							| 
									
										
										
										
											2019-04-11 11:33:27 +02:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #  error "unknown pointer size"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 15:20:52 +02:00
										 |  |  | PyAPI_FUNC(int) _PyMem_GetAllocatorName( | 
					
						
							|  |  |  |     const char *name, | 
					
						
							|  |  |  |     PyMemAllocatorName *allocator); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Configure the Python memory allocators.
 | 
					
						
							|  |  |  |    Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. | 
					
						
							|  |  |  |    PYMEM_ALLOCATOR_NOT_SET does nothing. */ | 
					
						
							|  |  |  | PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 01:11:10 +01:00
										 |  |  | /* bpo-35053: Expose _Py_tracemalloc_config for _Py_NewReference()
 | 
					
						
							|  |  |  |    which access directly _Py_tracemalloc_config.tracing for best | 
					
						
							|  |  |  |    performances. */ | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _PyTraceMalloc_Config_INIT \
 | 
					
						
							|  |  |  |     {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ | 
					
						
							|  |  |  |      .tracing = 0, \ | 
					
						
							| 
									
										
										
										
											2020-05-13 01:36:47 +02:00
										 |  |  |      .max_nframe = 1} | 
					
						
							| 
									
										
										
										
											2020-02-05 01:11:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 23:51:28 -06:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-05-24 17:01:38 +02:00
										 |  |  | #endif /* !Py_INTERNAL_PYMEM_H */
 |