/home/mdboom/Work/builds/cpython/Include/internal/pycore_pymem.h
Line | Count | Source (jump to first uncovered line) |
1 | #ifndef Py_INTERNAL_PYMEM_H |
2 | #define Py_INTERNAL_PYMEM_H |
3 | #ifdef __cplusplus |
4 | extern "C" { |
5 | #endif |
6 | |
7 | #ifndef Py_BUILD_CORE |
8 | # error "this header requires Py_BUILD_CORE define" |
9 | #endif |
10 | |
11 | #include "pymem.h" // PyMemAllocatorName |
12 | |
13 | |
14 | /* Set the memory allocator of the specified domain to the default. |
15 | Save the old allocator into *old_alloc if it's non-NULL. |
16 | Return on success, or return -1 if the domain is unknown. */ |
17 | PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( |
18 | PyMemAllocatorDomain domain, |
19 | PyMemAllocatorEx *old_alloc); |
20 | |
21 | /* Special bytes broadcast into debug memory blocks at appropriate times. |
22 | Strings of these are unlikely to be valid addresses, floats, ints or |
23 | 7-bit ASCII. |
24 | |
25 | - PYMEM_CLEANBYTE: clean (newly allocated) memory |
26 | - PYMEM_DEADBYTE dead (newly freed) memory |
27 | - PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block |
28 | |
29 | Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and |
30 | 0xFD to use the same values than Windows CRT debug malloc() and free(). |
31 | If modified, _PyMem_IsPtrFreed() should be updated as well. */ |
32 | #define PYMEM_CLEANBYTE 0xCD |
33 | #define PYMEM_DEADBYTE 0xDD |
34 | #define PYMEM_FORBIDDENBYTE 0xFD |
35 | |
36 | /* Heuristic checking if a pointer value is newly allocated |
37 | (uninitialized), newly freed or NULL (is equal to zero). |
38 | |
39 | The pointer is not dereferenced, only the pointer value is checked. |
40 | |
41 | The heuristic relies on the debug hooks on Python memory allocators which |
42 | fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory |
43 | with DEADBYTE (0xDD). Detect also "untouchable bytes" marked |
44 | with FORBIDDENBYTE (0xFD). */ |
45 | static inline int _PyMem_IsPtrFreed(const void *ptr) |
46 | { |
47 | uintptr_t value = (uintptr_t)ptr; |
48 | #if SIZEOF_VOID_P == 8 |
49 | return (value == 0 Branch (49:13): [True: 0, False: 0]
|
50 | || value == (uintptr_t)0xCDCDCDCDCDCDCDCD Branch (50:16): [True: 0, False: 0]
|
51 | || value == (uintptr_t)0xDDDDDDDDDDDDDDDD Branch (51:16): [True: 0, False: 0]
|
52 | || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); Branch (52:16): [True: 0, False: 0]
|
53 | #elif SIZEOF_VOID_P == 4 |
54 | return (value == 0 |
55 | || value == (uintptr_t)0xCDCDCDCD |
56 | || value == (uintptr_t)0xDDDDDDDD |
57 | || value == (uintptr_t)0xFDFDFDFD); |
58 | #else |
59 | # error "unknown pointer size" |
60 | #endif |
61 | } Unexecuted instantiation: bytesobject.c:_PyMem_IsPtrFreed Unexecuted instantiation: object.c:_PyMem_IsPtrFreed Unexecuted instantiation: obmalloc.c:_PyMem_IsPtrFreed Unexecuted instantiation: ceval.c:_PyMem_IsPtrFreed Unexecuted instantiation: compile.c:_PyMem_IsPtrFreed Unexecuted instantiation: import.c:_PyMem_IsPtrFreed Unexecuted instantiation: initconfig.c:_PyMem_IsPtrFreed Unexecuted instantiation: pathconfig.c:_PyMem_IsPtrFreed Unexecuted instantiation: preconfig.c:_PyMem_IsPtrFreed Unexecuted instantiation: pylifecycle.c:_PyMem_IsPtrFreed Unexecuted instantiation: pystate.c:_PyMem_IsPtrFreed Unexecuted instantiation: sysmodule.c:_PyMem_IsPtrFreed Unexecuted instantiation: _tracemalloc.c:_PyMem_IsPtrFreed Unexecuted instantiation: getpath.c:_PyMem_IsPtrFreed |
62 | |
63 | PyAPI_FUNC(int) _PyMem_GetAllocatorName( |
64 | const char *name, |
65 | PyMemAllocatorName *allocator); |
66 | |
67 | /* Configure the Python memory allocators. |
68 | Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. |
69 | PYMEM_ALLOCATOR_NOT_SET does nothing. */ |
70 | PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); |
71 | |
72 | struct _PyTraceMalloc_Config { |
73 | /* Module initialized? |
74 | Variable protected by the GIL */ |
75 | enum { |
76 | TRACEMALLOC_NOT_INITIALIZED, |
77 | TRACEMALLOC_INITIALIZED, |
78 | TRACEMALLOC_FINALIZED |
79 | } initialized; |
80 | |
81 | /* Is tracemalloc tracing memory allocations? |
82 | Variable protected by the GIL */ |
83 | int tracing; |
84 | |
85 | /* limit of the number of frames in a traceback, 1 by default. |
86 | Variable protected by the GIL. */ |
87 | int max_nframe; |
88 | }; |
89 | |
90 | #define _PyTraceMalloc_Config_INIT \ |
91 | {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ |
92 | .tracing = 0, \ |
93 | .max_nframe = 1} |
94 | |
95 | PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; |
96 | |
97 | /* Allocate memory directly from the O/S virtual memory system, |
98 | * where supported. Otherwise fallback on malloc */ |
99 | void *_PyObject_VirtualAlloc(size_t size); |
100 | void _PyObject_VirtualFree(void *, size_t size); |
101 | |
102 | /* This function returns the number of allocated memory blocks, regardless of size */ |
103 | PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); |
104 | |
105 | /* Macros */ |
106 | #ifdef WITH_PYMALLOC |
107 | // Export the symbol for the 3rd party guppy3 project |
108 | PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); |
109 | #endif |
110 | |
111 | #ifdef __cplusplus |
112 | } |
113 | #endif |
114 | #endif // !Py_INTERNAL_PYMEM_H |