10
10
11
11
#include <stdlib.h> // malloc()
12
12
#include <stdbool.h>
13
+ #ifdef WITH_MIMALLOC
14
+ #include "mimalloc.h"
15
+ #endif
13
16
14
17
#undef uint
15
18
#define uint pymem_uint
@@ -74,25 +77,100 @@ _PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr)
74
77
free (ptr );
75
78
}
76
79
80
+ #ifdef WITH_MIMALLOC
81
+
82
+ void *
83
+ _PyMem_MiMalloc (void * ctx , size_t size )
84
+ {
85
+ PyThreadState * tstate = _PyThreadState_GET ();
86
+ return mi_heap_malloc (tstate -> heaps [mi_heap_tag_default ], size );
87
+ }
88
+
89
+ void *
90
+ _PyMem_MiCalloc (void * ctx , size_t nelem , size_t elsize )
91
+ {
92
+ PyThreadState * tstate = _PyThreadState_GET ();
93
+ return mi_heap_calloc (tstate -> heaps [mi_heap_tag_default ], nelem , elsize );
94
+ }
95
+
96
+ void *
97
+ _PyMem_MiRealloc (void * ctx , void * ptr , size_t size )
98
+ {
99
+ PyThreadState * tstate = _PyThreadState_GET ();
100
+ return mi_heap_realloc (tstate -> heaps [mi_heap_tag_default ], ptr , size );
101
+ }
102
+
103
+ void
104
+ _PyMem_MiFree (void * ctx , void * ptr )
105
+ {
106
+ mi_free (ptr );
107
+ }
108
+
109
+ void *
110
+ _PyObject_MiMalloc (void * ctx , size_t nbytes )
111
+ {
112
+ PyThreadState * tstate = _PyThreadState_GET ();
113
+ return mi_heap_malloc (tstate -> heaps [mi_heap_tag_obj ], nbytes );
114
+ }
115
+
116
+ void *
117
+ _PyObject_MiCalloc (void * ctx , size_t nelem , size_t elsize )
118
+ {
119
+ PyThreadState * tstate = _PyThreadState_GET ();
120
+ return mi_heap_calloc (tstate -> heaps [mi_heap_tag_obj ], nelem , elsize );
121
+ }
122
+
123
+
124
+ void *
125
+ _PyObject_MiRealloc (void * ctx , void * ptr , size_t nbytes )
126
+ {
127
+ PyThreadState * tstate = _PyThreadState_GET ();
128
+ return mi_heap_realloc (tstate -> heaps [mi_heap_tag_obj ], ptr , nbytes );
129
+ }
130
+
131
+ void
132
+ _PyObject_MiFree (void * ctx , void * ptr )
133
+ {
134
+ mi_free (ptr );
135
+ }
136
+
137
+ #endif // WITH_MIMALLOC
138
+
139
+
77
140
#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
78
- #define PYRAW_ALLOC MALLOC_ALLOC
79
141
80
- /* the default object allocator */
142
+
143
+ #ifdef WITH_MIMALLOC
144
+ # define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree}
145
+ # define MIMALLOC_OBJALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree}
146
+ #endif
147
+
148
+ /* the pymalloc allocator */
81
149
82
150
// The actual implementation is further down.
83
151
84
- #ifdef WITH_PYMALLOC
152
+ #if defined( WITH_PYMALLOC )
85
153
void * _PyObject_Malloc (void * ctx , size_t size );
86
154
void * _PyObject_Calloc (void * ctx , size_t nelem , size_t elsize );
87
155
void _PyObject_Free (void * ctx , void * p );
88
156
void * _PyObject_Realloc (void * ctx , void * ptr , size_t size );
89
157
# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
158
+ #endif // WITH_PYMALLOC
159
+
160
+ #ifdef WITH_MIMALLOC
161
+ # define PYRAW_ALLOC MALLOC_ALLOC
162
+ # define PYMEM_ALLOC MIMALLOC_ALLOC
163
+ # define PYOBJ_ALLOC MIMALLOC_OBJALLOC
164
+ #elif defined(WITH_PYMALLOC )
165
+ # define PYRAW_ALLOC MALLOC_ALLOC
166
+ # define PYMEM_ALLOC PYMALLOC_ALLOC
90
167
# define PYOBJ_ALLOC PYMALLOC_ALLOC
91
168
#else
169
+ # define PYRAW_ALLOC MALLOC_ALLOC
170
+ # define PYMEM_ALLOC MALLOC_ALLOC
92
171
# define PYOBJ_ALLOC MALLOC_ALLOC
93
- #endif // WITH_PYMALLOC
172
+ #endif
94
173
95
- #define PYMEM_ALLOC PYOBJ_ALLOC
96
174
97
175
/* the default debug allocators */
98
176
@@ -291,6 +369,14 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator)
291
369
else if (strcmp (name , "pymalloc_debug ") == 0 ) {
292
370
* allocator = PYMEM_ALLOCATOR_PYMALLOC_DEBUG ;
293
371
}
372
+ #endif
373
+ #ifdef WITH_MIMALLOC
374
+ else if (strcmp (name , "mimalloc ") == 0 ) {
375
+ * allocator = PYMEM_ALLOCATOR_MIMALLOC ;
376
+ }
377
+ else if (strcmp (name , "mimalloc_debug" ) == 0 ) {
378
+ * allocator = PYMEM_ALLOCATOR_MIMALLOC_DEBUG ;
379
+ }
294
380
#endif
295
381
else if (strcmp (name , "malloc ") == 0 ) {
296
382
* allocator = PYMEM_ALLOCATOR_MALLOC ;
@@ -343,6 +429,26 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
343
429
break ;
344
430
}
345
431
#endif
432
+ #ifdef WITH_MIMALLOC
433
+ case PYMEM_ALLOCATOR_MIMALLOC :
434
+ case PYMEM_ALLOCATOR_MIMALLOC_DEBUG :
435
+ {
436
+ PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC ;
437
+ set_allocator_unlocked (PYMEM_DOMAIN_RAW , & malloc_alloc );
438
+
439
+ PyMemAllocatorEx pymalloc = MIMALLOC_ALLOC ;
440
+ set_allocator_unlocked (PYMEM_DOMAIN_MEM , & pymalloc );
441
+
442
+ PyMemAllocatorEx objmalloc = MIMALLOC_OBJALLOC ;
443
+ set_allocator_unlocked (PYMEM_DOMAIN_OBJ , & objmalloc );
444
+
445
+ if (allocator == PYMEM_ALLOCATOR_MIMALLOC_DEBUG ) {
446
+ set_up_debug_hooks_unlocked ();
447
+ }
448
+
449
+ break ;
450
+ }
451
+ #endif
346
452
347
453
case PYMEM_ALLOCATOR_MALLOC :
348
454
case PYMEM_ALLOCATOR_MALLOC_DEBUG :
@@ -390,6 +496,10 @@ get_current_allocator_name_unlocked(void)
390
496
#ifdef WITH_PYMALLOC
391
497
PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC ;
392
498
#endif
499
+ #ifdef WITH_MIMALLOC
500
+ PyMemAllocatorEx mimalloc = MIMALLOC_ALLOC ;
501
+ PyMemAllocatorEx mimalloc_obj = MIMALLOC_OBJALLOC ;
502
+ #endif
393
503
394
504
if (pymemallocator_eq (& _PyMem_Raw , & malloc_alloc ) &&
395
505
pymemallocator_eq (& _PyMem , & malloc_alloc ) &&
@@ -405,6 +515,14 @@ get_current_allocator_name_unlocked(void)
405
515
return "pymalloc" ;
406
516
}
407
517
#endif
518
+ #ifdef WITH_MIMALLOC
519
+ if (pymemallocator_eq (& _PyMem_Raw , & malloc_alloc ) &&
520
+ pymemallocator_eq (& _PyMem , & mimalloc ) &&
521
+ pymemallocator_eq (& _PyObject , & mimalloc_obj ))
522
+ {
523
+ return "mimalloc" ;
524
+ }
525
+ #endif
408
526
409
527
PyMemAllocatorEx dbg_raw = PYDBGRAW_ALLOC ;
410
528
PyMemAllocatorEx dbg_mem = PYDBGMEM_ALLOC ;
@@ -428,6 +546,14 @@ get_current_allocator_name_unlocked(void)
428
546
{
429
547
return "pymalloc_debug" ;
430
548
}
549
+ #endif
550
+ #ifdef WITH_MIMALLOC
551
+ if (pymemallocator_eq (& _PyMem_Debug .raw .alloc , & malloc_alloc ) &&
552
+ pymemallocator_eq (& _PyMem_Debug .mem .alloc , & mimalloc ) &&
553
+ pymemallocator_eq (& _PyMem_Debug .obj .alloc , & mimalloc_obj ))
554
+ {
555
+ return "mimalloc_debug" ;
556
+ }
431
557
#endif
432
558
}
433
559
return NULL ;
@@ -443,13 +569,14 @@ _PyMem_GetCurrentAllocatorName(void)
443
569
}
444
570
445
571
446
- #ifdef WITH_PYMALLOC
572
+ #if defined( WITH_PYMALLOC ) || defined( WITH_MIMALLOC )
447
573
static int
448
574
_PyMem_DebugEnabled (void )
449
575
{
450
576
return (_PyObject .malloc == _PyMem_DebugMalloc );
451
577
}
452
578
579
+ #ifdef WITH_PYMALLOC
453
580
static int
454
581
_PyMem_PymallocEnabled (void )
455
582
{
@@ -461,6 +588,19 @@ _PyMem_PymallocEnabled(void)
461
588
}
462
589
}
463
590
#endif
591
+ #ifdef WITH_MIMALLOC
592
+ static int
593
+ _PyMem_MimallocEnabled (void )
594
+ {
595
+ if (_PyMem_DebugEnabled ()) {
596
+ return (_PyMem_Debug .obj .alloc .malloc == _PyObject_MiMalloc );
597
+ }
598
+ else {
599
+ return (_PyObject .malloc == _PyObject_MiMalloc );
600
+ }
601
+ }
602
+ #endif
603
+ #endif // defined(WITH_PYMALLOC) || defined(WITH_MIMALLOC)
464
604
465
605
466
606
static void
0 commit comments