4
4
5
5
#include "pycore_obmalloc.h"
6
6
#include "pycore_pymem.h"
7
- #include "pycore_pymem_allocators.h"
8
7
8
+ #include <stdlib.h> // malloc()
9
9
#include <stdbool.h>
10
10
11
11
@@ -24,6 +24,149 @@ static void _PyMem_DebugCheckAddress(const char *func, char api_id, const void *
24
24
25
25
static void _PyMem_SetupDebugHooksDomain (PyMemAllocatorDomain domain );
26
26
27
+
28
+ /***************************************/
29
+ /* low-level allocator implementations */
30
+ /***************************************/
31
+
32
+ /* the default raw allocator (wraps malloc) */
33
+
34
+ void *
35
+ _PyMem_RawMalloc (void * Py_UNUSED (ctx ), size_t size )
36
+ {
37
+ /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL
38
+ for malloc(0), which would be treated as an error. Some platforms would
39
+ return a pointer with no memory behind it, which would break pymalloc.
40
+ To solve these problems, allocate an extra byte. */
41
+ if (size == 0 )
42
+ size = 1 ;
43
+ return malloc (size );
44
+ }
45
+
46
+ void *
47
+ _PyMem_RawCalloc (void * Py_UNUSED (ctx ), size_t nelem , size_t elsize )
48
+ {
49
+ /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL
50
+ for calloc(0, 0), which would be treated as an error. Some platforms
51
+ would return a pointer with no memory behind it, which would break
52
+ pymalloc. To solve these problems, allocate an extra byte. */
53
+ if (nelem == 0 || elsize == 0 ) {
54
+ nelem = 1 ;
55
+ elsize = 1 ;
56
+ }
57
+ return calloc (nelem , elsize );
58
+ }
59
+
60
+ void *
61
+ _PyMem_RawRealloc (void * Py_UNUSED (ctx ), void * ptr , size_t size )
62
+ {
63
+ if (size == 0 )
64
+ size = 1 ;
65
+ return realloc (ptr , size );
66
+ }
67
+
68
+ void
69
+ _PyMem_RawFree (void * Py_UNUSED (ctx ), void * ptr )
70
+ {
71
+ free (ptr );
72
+ }
73
+
74
+ #define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
75
+ #define PYRAW_ALLOC MALLOC_ALLOC
76
+
77
+ /* the default object allocator */
78
+
79
+ // The actual implementation is further down.
80
+
81
+ #ifdef WITH_PYMALLOC
82
+ void * _PyObject_Malloc (void * ctx , size_t size );
83
+ void * _PyObject_Calloc (void * ctx , size_t nelem , size_t elsize );
84
+ void _PyObject_Free (void * ctx , void * p );
85
+ void * _PyObject_Realloc (void * ctx , void * ptr , size_t size );
86
+ # define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
87
+ # define PYOBJ_ALLOC PYMALLOC_ALLOC
88
+ #else
89
+ # define PYOBJ_ALLOC MALLOC_ALLOC
90
+ #endif // WITH_PYMALLOC
91
+
92
+ #define PYMEM_ALLOC PYOBJ_ALLOC
93
+
94
+ /* the default debug allocators */
95
+
96
+ // The actual implementation is further down.
97
+
98
+ void * _PyMem_DebugRawMalloc (void * ctx , size_t size );
99
+ void * _PyMem_DebugRawCalloc (void * ctx , size_t nelem , size_t elsize );
100
+ void * _PyMem_DebugRawRealloc (void * ctx , void * ptr , size_t size );
101
+ void _PyMem_DebugRawFree (void * ctx , void * ptr );
102
+
103
+ void * _PyMem_DebugMalloc (void * ctx , size_t size );
104
+ void * _PyMem_DebugCalloc (void * ctx , size_t nelem , size_t elsize );
105
+ void * _PyMem_DebugRealloc (void * ctx , void * ptr , size_t size );
106
+ void _PyMem_DebugFree (void * ctx , void * p );
107
+
108
+ #define PYDBGRAW_ALLOC \
109
+ {&_PyRuntime.allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree}
110
+ #define PYDBGMEM_ALLOC \
111
+ {&_PyRuntime.allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree}
112
+ #define PYDBGOBJ_ALLOC \
113
+ {&_PyRuntime.allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree}
114
+
115
+ /* the low-level virtual memory allocator */
116
+
117
+ #ifdef WITH_PYMALLOC
118
+ # ifdef MS_WINDOWS
119
+ # include <windows.h>
120
+ # elif defined(HAVE_MMAP )
121
+ # include <sys/mman.h>
122
+ # ifdef MAP_ANONYMOUS
123
+ # define ARENAS_USE_MMAP
124
+ # endif
125
+ # endif
126
+ #endif
127
+
128
+ void *
129
+ _PyMem_ArenaAlloc (void * Py_UNUSED (ctx ), size_t size )
130
+ {
131
+ #ifdef MS_WINDOWS
132
+ return VirtualAlloc (NULL , size ,
133
+ MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
134
+ #elif defined(ARENAS_USE_MMAP )
135
+ void * ptr ;
136
+ ptr = mmap (NULL , size , PROT_READ |PROT_WRITE ,
137
+ MAP_PRIVATE |MAP_ANONYMOUS , -1 , 0 );
138
+ if (ptr == MAP_FAILED )
139
+ return NULL ;
140
+ assert (ptr != NULL );
141
+ return ptr ;
142
+ #else
143
+ return malloc (size );
144
+ #endif
145
+ }
146
+
147
+ void
148
+ _PyMem_ArenaFree (void * Py_UNUSED (ctx ), void * ptr ,
149
+ #if defined(ARENAS_USE_MMAP )
150
+ size_t size
151
+ #else
152
+ size_t Py_UNUSED (size )
153
+ #endif
154
+ )
155
+ {
156
+ #ifdef MS_WINDOWS
157
+ VirtualFree (ptr , 0 , MEM_RELEASE );
158
+ #elif defined(ARENAS_USE_MMAP )
159
+ munmap (ptr , size );
160
+ #else
161
+ free (ptr );
162
+ #endif
163
+ }
164
+
165
+ /*******************************************/
166
+ /* end low-level allocator implementations */
167
+ /*******************************************/
168
+
169
+
27
170
#if defined(__has_feature ) /* Clang */
28
171
# if __has_feature (address_sanitizer ) /* is ASAN enabled? */
29
172
# define _Py_NO_SANITIZE_ADDRESS \
0 commit comments