Coverage Report

Created: 2026-10-17 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Objects/obmalloc.c
Line
Count
Source
1
/* Python's malloc wrappers (see pymem.h) */
2
3
#include "Python.h"
4
#include "pycore_interp.h"        // _PyInterpreterState_HasFeature
5
#include "pycore_mmap.h"          // _PyAnnotateMemoryMap()
6
#include "pycore_object.h"        // _PyDebugAllocatorStats() definition
7
#include "pycore_obmalloc.h"
8
#include "pycore_obmalloc_init.h"
9
#include "pycore_pyerrors.h"      // _Py_FatalErrorFormat()
10
#include "pycore_pymem.h"
11
#include "pycore_pystate.h"       // _PyInterpreterState_GET
12
#include "pycore_stats.h"         // OBJECT_STAT_INC_COND()
13
14
#include <stdlib.h>               // malloc()
15
#include <stdbool.h>
16
#include <stdio.h>                // fopen(), fgets(), sscanf()
17
#include <errno.h>                // errno
18
#ifdef WITH_MIMALLOC
19
// Forward declarations of functions used in our mimalloc modifications
20
static void _PyMem_mi_page_clear_qsbr(mi_page_t *page);
21
static bool _PyMem_mi_page_is_safe_to_free(mi_page_t *page);
22
static bool _PyMem_mi_page_maybe_free(mi_page_t *page, mi_page_queue_t *pq, bool force);
23
static void _PyMem_mi_page_reclaimed(mi_page_t *page);
24
static void _PyMem_mi_heap_collect_qsbr(mi_heap_t *heap);
25
#  include "pycore_mimalloc.h"
26
#  include "mimalloc/static.c"
27
#  include "mimalloc/internal.h"  // for stats
28
#endif
29
30
#if defined(Py_GIL_DISABLED) && !defined(WITH_MIMALLOC)
31
#  error "Py_GIL_DISABLED requires WITH_MIMALLOC"
32
#endif
33
34
#undef  uint
35
2.00G
#define uint pymem_uint
36
37
38
/* Defined in tracemalloc.c */
39
extern void _PyMem_DumpTraceback(int fd, const void *ptr);
40
41
static void _PyObject_DebugDumpAddress(const void *p);
42
static void _PyMem_DebugCheckAddress(const char *func, char api_id, const void *p);
43
44
45
static void set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain);
46
static void set_up_debug_hooks_unlocked(void);
47
static void get_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *);
48
static void set_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *);
49
50
51
/***************************************/
52
/* low-level allocator implementations */
53
/***************************************/
54
55
/* the default raw allocator (wraps malloc) */
56
57
void *
58
_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size)
59
175M
{
60
    /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL
61
       for malloc(0), which would be treated as an error. Some platforms would
62
       return a pointer with no memory behind it, which would break pymalloc.
63
       To solve these problems, allocate an extra byte. */
64
175M
    if (size == 0)
65
51.4k
        size = 1;
66
175M
    return malloc(size);
67
175M
}
68
69
void *
70
_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize)
71
182k
{
72
    /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL
73
       for calloc(0, 0), which would be treated as an error. Some platforms
74
       would return a pointer with no memory behind it, which would break
75
       pymalloc.  To solve these problems, allocate an extra byte. */
76
182k
    if (nelem == 0 || elsize == 0) {
77
1.70k
        nelem = 1;
78
1.70k
        elsize = 1;
79
1.70k
    }
80
182k
    return calloc(nelem, elsize);
81
182k
}
82
83
void *
84
_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size)
85
9.77M
{
86
9.77M
    if (size == 0)
87
0
        size = 1;
88
9.77M
    return realloc(ptr, size);
89
9.77M
}
90
91
void
92
_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr)
93
175M
{
94
175M
    free(ptr);
95
175M
}
96
97
#ifdef WITH_MIMALLOC
98
99
static void
100
_PyMem_mi_page_clear_qsbr(mi_page_t *page)
101
0
{
102
#ifdef Py_GIL_DISABLED
103
    // Clear the QSBR goal and remove the page from the QSBR linked list.
104
    page->qsbr_goal = 0;
105
    if (page->qsbr_node.next != NULL) {
106
        llist_remove(&page->qsbr_node);
107
    }
108
#endif
109
0
}
110
111
// Check if an empty, newly reclaimed page is safe to free now.
112
static bool
113
_PyMem_mi_page_is_safe_to_free(mi_page_t *page)
114
0
{
115
0
    assert(mi_page_all_free(page));
116
#ifdef Py_GIL_DISABLED
117
    assert(page->qsbr_node.next == NULL);
118
    if (page->use_qsbr && page->qsbr_goal != 0) {
119
        _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
120
        if (tstate == NULL) {
121
            return false;
122
        }
123
        return _Py_qbsr_goal_reached(tstate->qsbr, page->qsbr_goal);
124
    }
125
#endif
126
0
    return true;
127
128
0
}
129
130
#ifdef Py_GIL_DISABLED
131
132
// If we are deferring collection of more than this amount of memory for
133
// mimalloc pages, advance the write sequence.  Advancing allows these
134
// pages to be re-used in a different thread or for a different size class.
135
#define QSBR_PAGE_MEM_LIMIT 4096*20
136
137
// Return true if the global write sequence should be advanced for a mimalloc
138
// page that is deferred from collection.
139
static bool
140
should_advance_qsbr_for_page(struct _qsbr_thread_state *qsbr, mi_page_t *page)
141
{
142
    size_t bsize = mi_page_block_size(page);
143
    size_t page_size = page->capacity*bsize;
144
    if (page_size > QSBR_PAGE_MEM_LIMIT) {
145
        qsbr->deferred_page_memory = 0;
146
        return true;
147
    }
148
    qsbr->deferred_page_memory += page_size;
149
    if (qsbr->deferred_page_memory > QSBR_PAGE_MEM_LIMIT) {
150
        qsbr->deferred_page_memory = 0;
151
        return true;
152
    }
153
    return false;
154
}
155
156
static _PyThreadStateImpl *
157
tstate_from_heap(mi_heap_t *heap)
158
{
159
    return _Py_CONTAINER_OF(heap->tld, _PyThreadStateImpl, mimalloc.tld);
160
}
161
#endif
162
163
static bool
164
_PyMem_mi_page_maybe_free(mi_page_t *page, mi_page_queue_t *pq, bool force)
165
0
{
166
#ifdef Py_GIL_DISABLED
167
    assert(mi_page_all_free(page));
168
    if (page->use_qsbr) {
169
        struct _qsbr_thread_state *qsbr = ((_PyThreadStateImpl *)PyThreadState_GET())->qsbr;
170
        if (page->qsbr_goal != 0 && _Py_qbsr_goal_reached(qsbr, page->qsbr_goal)) {
171
            _PyMem_mi_page_clear_qsbr(page);
172
            _mi_page_free(page, pq, force);
173
            return true;
174
        }
175
176
        // gh-145615: since we are not freeing this page yet, we want to
177
        // make it available for allocations. Note that the QSBR goal and
178
        // linked list node remain set even if the page is later used for
179
        // an allocation. We only detect and clear the QSBR goal when the
180
        // page becomes empty again (used == 0).
181
        if (mi_page_is_in_full(page)) {
182
            _mi_page_unfull(page);
183
        }
184
185
        _PyMem_mi_page_clear_qsbr(page);
186
        page->retire_expire = 0;
187
188
        if (should_advance_qsbr_for_page(qsbr, page)) {
189
            page->qsbr_goal = _Py_qsbr_advance(qsbr->shared);
190
        }
191
        else {
192
            page->qsbr_goal = _Py_qsbr_shared_next(qsbr->shared);
193
        }
194
195
        // We may be freeing a page belonging to a different thread during a
196
        // stop-the-world event. Find the _PyThreadStateImpl for the page.
197
        _PyThreadStateImpl *tstate = tstate_from_heap(mi_page_heap(page));
198
        llist_insert_tail(&tstate->mimalloc.page_list, &page->qsbr_node);
199
        return false;
200
    }
201
#endif
202
0
    _mi_page_free(page, pq, force);
203
0
    return true;
204
0
}
205
206
static void
207
_PyMem_mi_page_reclaimed(mi_page_t *page)
208
0
{
209
#ifdef Py_GIL_DISABLED
210
    assert(page->qsbr_node.next == NULL);
211
    if (page->qsbr_goal != 0) {
212
        if (mi_page_all_free(page)) {
213
            assert(page->qsbr_node.next == NULL);
214
            _PyThreadStateImpl *tstate = tstate_from_heap(mi_page_heap(page));
215
            assert(tstate == (_PyThreadStateImpl *)_PyThreadState_GET());
216
            page->retire_expire = 0;
217
            llist_insert_tail(&tstate->mimalloc.page_list, &page->qsbr_node);
218
        }
219
        else {
220
            page->qsbr_goal = 0;
221
        }
222
    }
223
#endif
224
0
}
225
226
static void
227
_PyMem_mi_heap_collect_qsbr(mi_heap_t *heap)
228
0
{
229
#ifdef Py_GIL_DISABLED
230
    if (!heap->page_use_qsbr) {
231
        return;
232
    }
233
234
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
235
    struct llist_node *head = &tstate->mimalloc.page_list;
236
    if (llist_empty(head)) {
237
        return;
238
    }
239
240
    struct llist_node *node;
241
    llist_for_each_safe(node, head) {
242
        mi_page_t *page = llist_data(node, mi_page_t, qsbr_node);
243
        if (!mi_page_all_free(page)) {
244
            // We allocated from this page some point after the delayed free
245
            _PyMem_mi_page_clear_qsbr(page);
246
            continue;
247
        }
248
249
        if (!_Py_qsbr_poll(tstate->qsbr, page->qsbr_goal)) {
250
            return;
251
        }
252
253
        _PyMem_mi_page_clear_qsbr(page);
254
        _mi_page_free(page, mi_page_queue_of(page), false);
255
    }
256
#endif
257
0
}
258
259
void *
260
_PyMem_MiMalloc(void *ctx, size_t size)
261
0
{
262
#ifdef Py_GIL_DISABLED
263
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
264
    mi_heap_t *heap = &tstate->mimalloc.heaps[_Py_MIMALLOC_HEAP_MEM];
265
    return mi_heap_malloc(heap, size);
266
#else
267
0
    return mi_malloc(size);
268
0
#endif
269
0
}
270
271
void *
272
_PyMem_MiCalloc(void *ctx, size_t nelem, size_t elsize)
273
0
{
274
#ifdef Py_GIL_DISABLED
275
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
276
    mi_heap_t *heap = &tstate->mimalloc.heaps[_Py_MIMALLOC_HEAP_MEM];
277
    return mi_heap_calloc(heap, nelem, elsize);
278
#else
279
0
    return mi_calloc(nelem, elsize);
280
0
#endif
281
0
}
282
283
void *
284
_PyMem_MiRealloc(void *ctx, void *ptr, size_t size)
285
0
{
286
#ifdef Py_GIL_DISABLED
287
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
288
    mi_heap_t *heap = &tstate->mimalloc.heaps[_Py_MIMALLOC_HEAP_MEM];
289
    return mi_heap_realloc(heap, ptr, size);
290
#else
291
0
    return mi_realloc(ptr, size);
292
0
#endif
293
0
}
294
295
void
296
_PyMem_MiFree(void *ctx, void *ptr)
297
0
{
298
0
    mi_free(ptr);
299
0
}
300
301
void *
302
_PyObject_MiMalloc(void *ctx, size_t nbytes)
303
0
{
304
#ifdef Py_GIL_DISABLED
305
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
306
    mi_heap_t *heap = tstate->mimalloc.current_object_heap;
307
    return mi_heap_malloc(heap, nbytes);
308
#else
309
0
    return mi_malloc(nbytes);
310
0
#endif
311
0
}
312
313
void *
314
_PyObject_MiCalloc(void *ctx, size_t nelem, size_t elsize)
315
0
{
316
#ifdef Py_GIL_DISABLED
317
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
318
    mi_heap_t *heap = tstate->mimalloc.current_object_heap;
319
    return mi_heap_calloc(heap, nelem, elsize);
320
#else
321
0
    return mi_calloc(nelem, elsize);
322
0
#endif
323
0
}
324
325
326
void *
327
_PyObject_MiRealloc(void *ctx, void *ptr, size_t nbytes)
328
0
{
329
#ifdef Py_GIL_DISABLED
330
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
331
    // Implement our own realloc logic so that we can copy PyObject header
332
    // in a thread-safe way.
333
    size_t size = mi_usable_size(ptr);
334
    if (nbytes <= size && nbytes >= (size / 2) && nbytes > 0) {
335
        return ptr;
336
    }
337
338
    mi_heap_t *heap = tstate->mimalloc.current_object_heap;
339
    void* newp = mi_heap_malloc(heap, nbytes);
340
    if (newp == NULL) {
341
        return NULL;
342
    }
343
344
    // Free threaded Python allows access from other threads to the PyObject reference count
345
    // fields for a period of time after the object is freed (see InternalDocs/qsbr.md).
346
    // These fields are typically initialized by PyObject_Init() using relaxed
347
    // atomic stores. We need to copy these fields in a thread-safe way here.
348
    // We use the "debug_offset" to determine how many bytes to copy -- it
349
    // includes the PyObject header and plus any extra pre-headers.
350
    size_t offset = heap->debug_offset;
351
    assert(offset % sizeof(void*) == 0);
352
353
    size_t copy_size = (size < nbytes ? size : nbytes);
354
    if (copy_size >= offset) {
355
        for (size_t i = 0; i != offset; i += sizeof(void*)) {
356
            // Use memcpy to avoid strict-aliasing issues. However, we probably
357
            // still have unavoidable strict-aliasing issues with
358
            // _Py_atomic_store_ptr_relaxed here.
359
            void *word;
360
            memcpy(&word, (char*)ptr + i, sizeof(void*));
361
            _Py_atomic_store_ptr_relaxed((void**)((char*)newp + i), word);
362
        }
363
        _mi_memcpy((char*)newp + offset, (char*)ptr + offset, copy_size - offset);
364
    }
365
    else {
366
        // memcpy(dst, NULL, 0) is undefined behavior. See gh-151297.
367
        if mi_likely(ptr) {
368
            _mi_memcpy(newp, ptr, copy_size);
369
        }
370
    }
371
    mi_free(ptr);
372
    return newp;
373
#else
374
0
    return mi_realloc(ptr, nbytes);
375
0
#endif
376
0
}
377
378
void
379
_PyObject_MiFree(void *ctx, void *ptr)
380
0
{
381
0
    mi_free(ptr);
382
0
}
383
384
void *
385
_PyMem_MiRawMalloc(void *ctx, size_t size)
386
0
{
387
0
    return mi_malloc(size);
388
0
}
389
390
void *
391
_PyMem_MiRawCalloc(void *ctx, size_t nelem, size_t elsize)
392
0
{
393
0
    return mi_calloc(nelem, elsize);
394
0
}
395
396
void *
397
_PyMem_MiRawRealloc(void *ctx, void *ptr, size_t size)
398
0
{
399
0
    return mi_realloc(ptr, size);
400
0
}
401
402
void
403
_PyMem_MiRawFree(void *ctx, void *ptr)
404
0
{
405
0
    mi_free(ptr);
406
0
}
407
#endif // WITH_MIMALLOC
408
409
410
0
#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
411
412
413
#ifdef WITH_MIMALLOC
414
0
#  define MIMALLOC_ALLOC    {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree}
415
0
#  define MIMALLOC_RAWALLOC {NULL, _PyMem_MiRawMalloc, _PyMem_MiRawCalloc, _PyMem_MiRawRealloc, _PyMem_MiRawFree}
416
0
#  define MIMALLOC_OBJALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree}
417
#endif
418
419
/* the pymalloc allocator */
420
421
// The actual implementation is further down.
422
423
#if defined(WITH_PYMALLOC)
424
void* _PyObject_Malloc(void *ctx, size_t size);
425
void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize);
426
void _PyObject_Free(void *ctx, void *p);
427
void* _PyObject_Realloc(void *ctx, void *ptr, size_t size);
428
0
#  define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
429
#endif  // WITH_PYMALLOC
430
431
#if defined(Py_GIL_DISABLED)
432
// Py_GIL_DISABLED requires using mimalloc for "mem" and "obj" domains.
433
#  define PYRAW_ALLOC MIMALLOC_RAWALLOC
434
#  define PYMEM_ALLOC MIMALLOC_ALLOC
435
#  define PYOBJ_ALLOC MIMALLOC_OBJALLOC
436
#elif defined(_Py_ADDRESS_SANITIZER) || defined(_Py_MEMORY_SANITIZER)
437
// ASan and MSan do not track pymalloc blocks, so use malloc by default.
438
// pymalloc can still be selected at runtime.
439
#  define PYRAW_ALLOC MALLOC_ALLOC
440
#  define PYMEM_ALLOC MALLOC_ALLOC
441
#  define PYOBJ_ALLOC MALLOC_ALLOC
442
#elif defined(WITH_PYMALLOC)
443
0
#  define PYRAW_ALLOC MALLOC_ALLOC
444
0
#  define PYMEM_ALLOC PYMALLOC_ALLOC
445
0
#  define PYOBJ_ALLOC PYMALLOC_ALLOC
446
#else
447
#  define PYRAW_ALLOC MALLOC_ALLOC
448
#  define PYMEM_ALLOC MALLOC_ALLOC
449
#  define PYOBJ_ALLOC MALLOC_ALLOC
450
#endif
451
452
453
/* the default debug allocators */
454
455
// The actual implementation is further down.
456
457
void* _PyMem_DebugRawMalloc(void *ctx, size_t size);
458
void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize);
459
void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size);
460
void _PyMem_DebugRawFree(void *ctx, void *ptr);
461
462
void* _PyMem_DebugMalloc(void *ctx, size_t size);
463
void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize);
464
void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size);
465
void _PyMem_DebugFree(void *ctx, void *p);
466
467
#define PYDBGRAW_ALLOC \
468
0
    {&_PyRuntime.allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree}
469
#define PYDBGMEM_ALLOC \
470
0
    {&_PyRuntime.allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree}
471
#define PYDBGOBJ_ALLOC \
472
0
    {&_PyRuntime.allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree}
473
474
/* default raw allocator (not swappable) */
475
476
void *
477
_PyMem_DefaultRawMalloc(size_t size)
478
296
{
479
#ifdef Py_DEBUG
480
    return _PyMem_DebugRawMalloc(&_PyRuntime.allocators.debug.raw, size);
481
#else
482
296
    return _PyMem_RawMalloc(NULL, size);
483
296
#endif
484
296
}
485
486
void *
487
_PyMem_DefaultRawCalloc(size_t nelem, size_t elsize)
488
0
{
489
#ifdef Py_DEBUG
490
    return _PyMem_DebugRawCalloc(&_PyRuntime.allocators.debug.raw, nelem, elsize);
491
#else
492
0
    return _PyMem_RawCalloc(NULL, nelem, elsize);
493
0
#endif
494
0
}
495
496
void *
497
_PyMem_DefaultRawRealloc(void *ptr, size_t size)
498
0
{
499
#ifdef Py_DEBUG
500
    return _PyMem_DebugRawRealloc(&_PyRuntime.allocators.debug.raw, ptr, size);
501
#else
502
0
    return _PyMem_RawRealloc(NULL, ptr, size);
503
0
#endif
504
0
}
505
506
void
507
_PyMem_DefaultRawFree(void *ptr)
508
333
{
509
#ifdef Py_DEBUG
510
    _PyMem_DebugRawFree(&_PyRuntime.allocators.debug.raw, ptr);
511
#else
512
333
    _PyMem_RawFree(NULL, ptr);
513
333
#endif
514
333
}
515
516
wchar_t*
517
_PyMem_DefaultRawWcsdup(const wchar_t *str)
518
222
{
519
222
    assert(str != NULL);
520
521
222
    size_t len = wcslen(str);
522
222
    if (len > (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) {
523
0
        return NULL;
524
0
    }
525
526
222
    size_t size = (len + 1) * sizeof(wchar_t);
527
222
    wchar_t *str2 = _PyMem_DefaultRawMalloc(size);
528
222
    if (str2 == NULL) {
529
0
        return NULL;
530
0
    }
531
532
222
    memcpy(str2, str, size);
533
222
    return str2;
534
222
}
535
536
/* the low-level virtual memory allocator */
537
538
#ifdef WITH_PYMALLOC
539
#  ifdef MS_WINDOWS
540
#    include <windows.h>
541
#  elif defined(HAVE_MMAP)
542
#    include <sys/mman.h>
543
#    ifdef MAP_ANONYMOUS
544
#      define ARENAS_USE_MMAP
545
#    endif
546
#  endif
547
#endif
548
549
/* Return the system's default huge page size in bytes, or 0 if it
550
 * cannot be determined.  The result is cached after the first call.
551
 *
552
 * This is Linux-only (/proc/meminfo).  On other systems that define
553
 * MAP_HUGETLB the caller should skip huge pages gracefully. */
554
#if defined(PYMALLOC_USE_HUGEPAGES) && defined(ARENAS_USE_MMAP) && defined(MAP_HUGETLB)
555
static size_t
556
_pymalloc_system_hugepage_size(void)
557
{
558
    static size_t hp_size = 0;
559
    static int initialized = 0;
560
561
    if (initialized) {
562
        return hp_size;
563
    }
564
565
#ifdef __linux__
566
    FILE *f = fopen("/proc/meminfo", "r");
567
    if (f != NULL) {
568
        char line[256];
569
        while (fgets(line, sizeof(line), f)) {
570
            unsigned long size_kb;
571
            if (sscanf(line, "Hugepagesize: %lu kB", &size_kb) == 1) {
572
                hp_size = (size_t)size_kb * 1024;
573
                break;
574
            }
575
        }
576
        fclose(f);
577
    }
578
#endif
579
580
    initialized = 1;
581
    return hp_size;
582
}
583
#endif
584
585
#if (defined(MS_WINDOWS) && defined(PYMALLOC_USE_HUGEPAGES)) || \
586
    (defined(PYMALLOC_USE_HUGEPAGES) && defined(ARENAS_USE_MMAP) && defined(MAP_HUGETLB))
587
static size_t
588
_pymalloc_round_up_to_multiple(size_t size, size_t multiple)
589
{
590
    if (multiple == 0 || size == 0) {
591
        return size;
592
    }
593
594
    size_t remainder = size % multiple;
595
    if (remainder == 0) {
596
        return size;
597
    }
598
599
    size_t padding = multiple - remainder;
600
    if (size > SIZE_MAX - padding) {
601
        return 0;
602
    }
603
    return size + padding;
604
}
605
#endif
606
607
static size_t
608
_pymalloc_virtual_alloc_size(size_t size)
609
65.8k
{
610
#if defined(MS_WINDOWS) && defined(PYMALLOC_USE_HUGEPAGES)
611
    if (_PyRuntime.allocators.use_hugepages) {
612
        SIZE_T large_page_size = GetLargePageMinimum();
613
        if (large_page_size > 0) {
614
            return _pymalloc_round_up_to_multiple(size, (size_t)large_page_size);
615
        }
616
    }
617
#elif defined(PYMALLOC_USE_HUGEPAGES) && defined(ARENAS_USE_MMAP) && defined(MAP_HUGETLB)
618
    if (_PyRuntime.allocators.use_hugepages) {
619
        size_t hp_size = _pymalloc_system_hugepage_size();
620
        if (hp_size > 0) {
621
            return _pymalloc_round_up_to_multiple(size, hp_size);
622
        }
623
    }
624
#endif
625
65.8k
    return size;
626
65.8k
}
627
628
void *
629
_PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size)
630
41.9k
{
631
#ifdef MS_WINDOWS
632
#  ifdef PYMALLOC_USE_HUGEPAGES
633
    if (_PyRuntime.allocators.use_hugepages) {
634
        SIZE_T lp_size = GetLargePageMinimum();
635
        if (lp_size > 0 && size % lp_size == 0) {
636
            void *ptr = VirtualAlloc(NULL, size,
637
                            MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES,
638
                            PAGE_READWRITE);
639
            if (ptr != NULL)
640
                return ptr;
641
        }
642
    }
643
    /* Fall back to regular pages */
644
#  endif
645
    return VirtualAlloc(NULL, size,
646
                        MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
647
#elif defined(ARENAS_USE_MMAP)
648
    void *ptr;
649
#  ifdef PYMALLOC_USE_HUGEPAGES
650
#    ifdef MAP_HUGETLB
651
    if (_PyRuntime.allocators.use_hugepages) {
652
        size_t hp_size = _pymalloc_system_hugepage_size();
653
        /* Only use huge pages if the arena size is a multiple of the
654
         * system's default huge page size.  When the arena is smaller
655
         * than the huge page, mmap still succeeds but silently
656
         * allocates an entire huge page; the subsequent munmap with
657
         * the smaller arena size then fails with EINVAL, leaking
658
         * all of that memory. */
659
        if (hp_size > 0 && size % hp_size == 0) {
660
            ptr = mmap(NULL, size, PROT_READ|PROT_WRITE,
661
                       MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0);
662
            if (ptr != MAP_FAILED) {
663
                assert(ptr != NULL);
664
                (void)_PyAnnotateMemoryMap(ptr, size, "cpython:pymalloc:hugepage");
665
                return ptr;
666
            }
667
        }
668
    }
669
    /* Fall back to regular pages */
670
#    endif
671
#  endif
672
41.9k
    ptr = mmap(NULL, size, PROT_READ|PROT_WRITE,
673
41.9k
               MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
674
41.9k
    if (ptr == MAP_FAILED)
675
0
        return NULL;
676
41.9k
    assert(ptr != NULL);
677
41.9k
#ifdef MADV_HUGEPAGE
678
41.9k
    (void)madvise(ptr, size, MADV_HUGEPAGE);
679
41.9k
#endif
680
41.9k
    (void)_PyAnnotateMemoryMap(ptr, size, "cpython:pymalloc");
681
41.9k
    return ptr;
682
#else
683
    return malloc(size);
684
#endif
685
41.9k
}
686
687
void
688
_PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr,
689
#if defined(ARENAS_USE_MMAP)
690
    size_t size
691
#else
692
    size_t Py_UNUSED(size)
693
#endif
694
)
695
41.2k
{
696
#ifdef MS_WINDOWS
697
    /* Unlike free(), VirtualFree() does not special-case NULL to noop. */
698
    if (ptr == NULL) {
699
        return;
700
    }
701
    VirtualFree(ptr, 0, MEM_RELEASE);
702
#elif defined(ARENAS_USE_MMAP)
703
    /* Unlike free(), munmap() does not special-case NULL to noop. */
704
41.2k
    if (ptr == NULL) {
705
0
        return;
706
0
    }
707
41.2k
    if (munmap(ptr, size) < 0) {
708
0
        _Py_FatalErrorFormat(__func__,
709
0
                             "munmap(%p, %zu) failed with errno %d",
710
0
                             ptr, size, errno);
711
0
    }
712
#else
713
    free(ptr);
714
#endif
715
41.2k
}
716
717
/*******************************************/
718
/* end low-level allocator implementations */
719
/*******************************************/
720
721
722
74
#define ALLOCATORS_MUTEX (_PyRuntime.allocators.mutex)
723
721M
#define _PyMem_Raw (_PyRuntime.allocators.standard.raw)
724
1.95G
#define _PyMem (_PyRuntime.allocators.standard.mem)
725
6.11G
#define _PyObject (_PyRuntime.allocators.standard.obj)
726
0
#define _PyMem_Debug (_PyRuntime.allocators.debug)
727
166k
#define _PyObject_Arena (_PyRuntime.allocators.obj_arena)
728
729
730
/***************************/
731
/* managing the allocators */
732
/***************************/
733
734
static int
735
set_default_allocator_unlocked(PyMemAllocatorDomain domain, int debug,
736
                               PyMemAllocatorEx *old_alloc)
737
0
{
738
0
    if (old_alloc != NULL) {
739
0
        get_allocator_unlocked(domain, old_alloc);
740
0
    }
741
742
743
0
    PyMemAllocatorEx new_alloc;
744
0
    switch(domain)
745
0
    {
746
0
    case PYMEM_DOMAIN_RAW:
747
0
        new_alloc = (PyMemAllocatorEx)PYRAW_ALLOC;
748
0
        break;
749
0
    case PYMEM_DOMAIN_MEM:
750
0
        new_alloc = (PyMemAllocatorEx)PYMEM_ALLOC;
751
0
        break;
752
0
    case PYMEM_DOMAIN_OBJ:
753
0
        new_alloc = (PyMemAllocatorEx)PYOBJ_ALLOC;
754
0
        break;
755
0
    default:
756
        /* unknown domain */
757
0
        return -1;
758
0
    }
759
0
    set_allocator_unlocked(domain, &new_alloc);
760
0
    if (debug) {
761
0
        set_up_debug_hooks_domain_unlocked(domain);
762
0
    }
763
0
    return 0;
764
0
}
765
766
767
#ifdef Py_DEBUG
768
static const int pydebug = 1;
769
#else
770
static const int pydebug = 0;
771
#endif
772
773
int
774
_PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator)
775
0
{
776
0
    if (name == NULL || *name == '\0') {
777
        /* PYTHONMALLOC is empty or is not set or ignored (-E/-I command line
778
           nameions): use default memory allocators */
779
0
        *allocator = PYMEM_ALLOCATOR_DEFAULT;
780
0
    }
781
0
    else if (strcmp(name, "default") == 0) {
782
0
        *allocator = PYMEM_ALLOCATOR_DEFAULT;
783
0
    }
784
0
    else if (strcmp(name, "debug") == 0) {
785
0
        *allocator = PYMEM_ALLOCATOR_DEBUG;
786
0
    }
787
0
#if defined(WITH_PYMALLOC) && !defined(Py_GIL_DISABLED)
788
0
    else if (strcmp(name, "pymalloc") == 0) {
789
0
        *allocator = PYMEM_ALLOCATOR_PYMALLOC;
790
0
    }
791
0
    else if (strcmp(name, "pymalloc_debug") == 0) {
792
0
        *allocator = PYMEM_ALLOCATOR_PYMALLOC_DEBUG;
793
0
    }
794
0
#endif
795
0
#ifdef WITH_MIMALLOC
796
0
    else if (strcmp(name, "mimalloc") == 0) {
797
0
        *allocator = PYMEM_ALLOCATOR_MIMALLOC;
798
0
    }
799
0
    else if (strcmp(name, "mimalloc_debug") == 0) {
800
0
        *allocator = PYMEM_ALLOCATOR_MIMALLOC_DEBUG;
801
0
    }
802
0
#endif
803
0
#ifndef Py_GIL_DISABLED
804
0
    else if (strcmp(name, "malloc") == 0) {
805
0
        *allocator = PYMEM_ALLOCATOR_MALLOC;
806
0
    }
807
0
    else if (strcmp(name, "malloc_debug") == 0) {
808
0
        *allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG;
809
0
    }
810
0
#endif
811
0
    else {
812
        /* unknown allocator */
813
0
        return -1;
814
0
    }
815
0
    return 0;
816
0
}
817
818
819
static int
820
set_up_allocators_unlocked(PyMemAllocatorName allocator)
821
0
{
822
0
    switch (allocator) {
823
0
    case PYMEM_ALLOCATOR_NOT_SET:
824
        /* do nothing */
825
0
        break;
826
827
0
    case PYMEM_ALLOCATOR_DEFAULT:
828
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, pydebug, NULL);
829
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, pydebug, NULL);
830
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, pydebug, NULL);
831
0
        _PyRuntime.allocators.is_debug_enabled = pydebug;
832
0
        break;
833
834
0
    case PYMEM_ALLOCATOR_DEBUG:
835
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, 1, NULL);
836
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, 1, NULL);
837
0
        (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, 1, NULL);
838
0
        _PyRuntime.allocators.is_debug_enabled = 1;
839
0
        break;
840
841
0
#ifdef WITH_PYMALLOC
842
0
    case PYMEM_ALLOCATOR_PYMALLOC:
843
0
    case PYMEM_ALLOCATOR_PYMALLOC_DEBUG:
844
0
    {
845
0
        PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC;
846
0
        set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc);
847
848
0
        PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC;
849
0
        set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc);
850
0
        set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &pymalloc);
851
852
0
        int is_debug = (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG);
853
0
        _PyRuntime.allocators.is_debug_enabled = is_debug;
854
0
        if (is_debug) {
855
0
            set_up_debug_hooks_unlocked();
856
0
        }
857
0
        break;
858
0
    }
859
0
#endif
860
0
#ifdef WITH_MIMALLOC
861
0
    case PYMEM_ALLOCATOR_MIMALLOC:
862
0
    case PYMEM_ALLOCATOR_MIMALLOC_DEBUG:
863
0
    {
864
0
        PyMemAllocatorEx malloc_alloc = MIMALLOC_RAWALLOC;
865
0
        set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc);
866
867
0
        PyMemAllocatorEx pymalloc = MIMALLOC_ALLOC;
868
0
        set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc);
869
870
0
        PyMemAllocatorEx objmalloc = MIMALLOC_OBJALLOC;
871
0
        set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &objmalloc);
872
873
0
        int is_debug = (allocator == PYMEM_ALLOCATOR_MIMALLOC_DEBUG);
874
0
        _PyRuntime.allocators.is_debug_enabled = is_debug;
875
0
        if (is_debug) {
876
0
            set_up_debug_hooks_unlocked();
877
0
        }
878
879
0
        break;
880
0
    }
881
0
#endif
882
883
0
    case PYMEM_ALLOCATOR_MALLOC:
884
0
    case PYMEM_ALLOCATOR_MALLOC_DEBUG:
885
0
    {
886
0
        PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC;
887
0
        set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc);
888
0
        set_allocator_unlocked(PYMEM_DOMAIN_MEM, &malloc_alloc);
889
0
        set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &malloc_alloc);
890
891
0
        int is_debug = (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG);
892
0
        _PyRuntime.allocators.is_debug_enabled = is_debug;
893
0
        if (is_debug) {
894
0
            set_up_debug_hooks_unlocked();
895
0
        }
896
0
        break;
897
0
    }
898
899
0
    default:
900
        /* unknown allocator */
901
0
        return -1;
902
0
    }
903
904
0
    return 0;
905
0
}
906
907
int
908
_PyMem_SetupAllocators(PyMemAllocatorName allocator)
909
0
{
910
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
911
0
    int res = set_up_allocators_unlocked(allocator);
912
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
913
0
    return res;
914
0
}
915
916
917
static int
918
pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b)
919
0
{
920
0
    return (memcmp(a, b, sizeof(PyMemAllocatorEx)) == 0);
921
0
}
922
923
924
static const char*
925
get_current_allocator_name_unlocked(void)
926
0
{
927
0
    PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC;
928
0
#ifdef WITH_PYMALLOC
929
0
    PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC;
930
0
#endif
931
0
#ifdef WITH_MIMALLOC
932
0
    PyMemAllocatorEx mimalloc = MIMALLOC_ALLOC;
933
0
    PyMemAllocatorEx mimalloc_obj = MIMALLOC_OBJALLOC;
934
0
    PyMemAllocatorEx mimalloc_raw = MIMALLOC_RAWALLOC;
935
0
#endif
936
937
0
    if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) &&
938
0
        pymemallocator_eq(&_PyMem, &malloc_alloc) &&
939
0
        pymemallocator_eq(&_PyObject, &malloc_alloc))
940
0
    {
941
0
        return "malloc";
942
0
    }
943
0
#ifdef WITH_PYMALLOC
944
0
    if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) &&
945
0
        pymemallocator_eq(&_PyMem, &pymalloc) &&
946
0
        pymemallocator_eq(&_PyObject, &pymalloc))
947
0
    {
948
0
        return "pymalloc";
949
0
    }
950
0
#endif
951
0
#ifdef WITH_MIMALLOC
952
0
    if (pymemallocator_eq(&_PyMem_Raw, &mimalloc_raw) &&
953
0
        pymemallocator_eq(&_PyMem, &mimalloc) &&
954
0
        pymemallocator_eq(&_PyObject, &mimalloc_obj))
955
0
    {
956
0
        return "mimalloc";
957
0
    }
958
0
#endif
959
960
0
    PyMemAllocatorEx dbg_raw = PYDBGRAW_ALLOC;
961
0
    PyMemAllocatorEx dbg_mem = PYDBGMEM_ALLOC;
962
0
    PyMemAllocatorEx dbg_obj = PYDBGOBJ_ALLOC;
963
964
0
    if (pymemallocator_eq(&_PyMem_Raw, &dbg_raw) &&
965
0
        pymemallocator_eq(&_PyMem, &dbg_mem) &&
966
0
        pymemallocator_eq(&_PyObject, &dbg_obj))
967
0
    {
968
        /* Debug hooks installed */
969
0
        if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) &&
970
0
            pymemallocator_eq(&_PyMem_Debug.mem.alloc, &malloc_alloc) &&
971
0
            pymemallocator_eq(&_PyMem_Debug.obj.alloc, &malloc_alloc))
972
0
        {
973
0
            return "malloc_debug";
974
0
        }
975
0
#ifdef WITH_PYMALLOC
976
0
        if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) &&
977
0
            pymemallocator_eq(&_PyMem_Debug.mem.alloc, &pymalloc) &&
978
0
            pymemallocator_eq(&_PyMem_Debug.obj.alloc, &pymalloc))
979
0
        {
980
0
            return "pymalloc_debug";
981
0
        }
982
0
#endif
983
0
#ifdef WITH_MIMALLOC
984
0
        if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &mimalloc_raw) &&
985
0
            pymemallocator_eq(&_PyMem_Debug.mem.alloc, &mimalloc) &&
986
0
            pymemallocator_eq(&_PyMem_Debug.obj.alloc, &mimalloc_obj))
987
0
        {
988
0
            return "mimalloc_debug";
989
0
        }
990
0
#endif
991
0
    }
992
0
    return NULL;
993
0
}
994
995
const char*
996
_PyMem_GetCurrentAllocatorName(void)
997
0
{
998
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
999
0
    const char *name = get_current_allocator_name_unlocked();
1000
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1001
0
    return name;
1002
0
}
1003
1004
1005
int
1006
_PyMem_DebugEnabled(void)
1007
0
{
1008
0
    return _PyRuntime.allocators.is_debug_enabled;
1009
0
}
1010
1011
#ifdef WITH_PYMALLOC
1012
static int
1013
_PyMem_PymallocEnabled(void)
1014
0
{
1015
0
    if (_PyMem_DebugEnabled()) {
1016
0
        return (_PyMem_Debug.obj.alloc.malloc == _PyObject_Malloc);
1017
0
    }
1018
0
    else {
1019
0
        return (_PyObject.malloc == _PyObject_Malloc);
1020
0
    }
1021
0
}
1022
1023
#ifdef WITH_MIMALLOC
1024
static int
1025
_PyMem_MimallocEnabled(void)
1026
0
{
1027
#ifdef Py_GIL_DISABLED
1028
    return 1;
1029
#else
1030
0
    if (_PyMem_DebugEnabled()) {
1031
0
        return (_PyMem_Debug.obj.alloc.malloc == _PyObject_MiMalloc);
1032
0
    }
1033
0
    else {
1034
0
        return (_PyObject.malloc == _PyObject_MiMalloc);
1035
0
    }
1036
0
#endif
1037
0
}
1038
#endif  // WITH_MIMALLOC
1039
1040
#endif  // WITH_PYMALLOC
1041
1042
1043
static void
1044
set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain)
1045
0
{
1046
0
    PyMemAllocatorEx alloc;
1047
1048
0
    if (domain == PYMEM_DOMAIN_RAW) {
1049
0
        if (_PyMem_Raw.malloc == _PyMem_DebugRawMalloc) {
1050
0
            return;
1051
0
        }
1052
1053
0
        get_allocator_unlocked(domain, &_PyMem_Debug.raw.alloc);
1054
0
        alloc.ctx = &_PyMem_Debug.raw;
1055
0
        alloc.malloc = _PyMem_DebugRawMalloc;
1056
0
        alloc.calloc = _PyMem_DebugRawCalloc;
1057
0
        alloc.realloc = _PyMem_DebugRawRealloc;
1058
0
        alloc.free = _PyMem_DebugRawFree;
1059
0
        set_allocator_unlocked(domain, &alloc);
1060
0
    }
1061
0
    else if (domain == PYMEM_DOMAIN_MEM) {
1062
0
        if (_PyMem.malloc == _PyMem_DebugMalloc) {
1063
0
            return;
1064
0
        }
1065
1066
0
        get_allocator_unlocked(domain, &_PyMem_Debug.mem.alloc);
1067
0
        alloc.ctx = &_PyMem_Debug.mem;
1068
0
        alloc.malloc = _PyMem_DebugMalloc;
1069
0
        alloc.calloc = _PyMem_DebugCalloc;
1070
0
        alloc.realloc = _PyMem_DebugRealloc;
1071
0
        alloc.free = _PyMem_DebugFree;
1072
0
        set_allocator_unlocked(domain, &alloc);
1073
0
    }
1074
0
    else if (domain == PYMEM_DOMAIN_OBJ)  {
1075
0
        if (_PyObject.malloc == _PyMem_DebugMalloc) {
1076
0
            return;
1077
0
        }
1078
1079
0
        get_allocator_unlocked(domain, &_PyMem_Debug.obj.alloc);
1080
0
        alloc.ctx = &_PyMem_Debug.obj;
1081
0
        alloc.malloc = _PyMem_DebugMalloc;
1082
0
        alloc.calloc = _PyMem_DebugCalloc;
1083
0
        alloc.realloc = _PyMem_DebugRealloc;
1084
0
        alloc.free = _PyMem_DebugFree;
1085
0
        set_allocator_unlocked(domain, &alloc);
1086
0
    }
1087
0
}
1088
1089
1090
static void
1091
set_up_debug_hooks_unlocked(void)
1092
0
{
1093
0
    set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_RAW);
1094
0
    set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_MEM);
1095
0
    set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_OBJ);
1096
0
    _PyRuntime.allocators.is_debug_enabled = 1;
1097
0
}
1098
1099
void
1100
PyMem_SetupDebugHooks(void)
1101
0
{
1102
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
1103
0
    set_up_debug_hooks_unlocked();
1104
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1105
0
}
1106
1107
static void
1108
get_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
1109
37
{
1110
37
    switch(domain)
1111
37
    {
1112
37
    case PYMEM_DOMAIN_RAW: *allocator = _PyMem_Raw; break;
1113
0
    case PYMEM_DOMAIN_MEM: *allocator = _PyMem; break;
1114
0
    case PYMEM_DOMAIN_OBJ: *allocator = _PyObject; break;
1115
0
    default:
1116
        /* unknown domain: set all attributes to NULL */
1117
0
        allocator->ctx = NULL;
1118
0
        allocator->malloc = NULL;
1119
0
        allocator->calloc = NULL;
1120
0
        allocator->realloc = NULL;
1121
0
        allocator->free = NULL;
1122
37
    }
1123
37
}
1124
1125
static void
1126
set_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
1127
0
{
1128
0
    switch(domain)
1129
0
    {
1130
0
    case PYMEM_DOMAIN_RAW: _PyMem_Raw = *allocator; break;
1131
0
    case PYMEM_DOMAIN_MEM: _PyMem = *allocator; break;
1132
0
    case PYMEM_DOMAIN_OBJ: _PyObject = *allocator; break;
1133
    /* ignore unknown domain */
1134
0
    }
1135
0
}
1136
1137
void
1138
PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
1139
37
{
1140
37
    PyMutex_Lock(&ALLOCATORS_MUTEX);
1141
37
    get_allocator_unlocked(domain, allocator);
1142
37
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1143
37
}
1144
1145
void
1146
PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
1147
0
{
1148
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
1149
0
    set_allocator_unlocked(domain, allocator);
1150
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1151
0
}
1152
1153
void
1154
PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)
1155
0
{
1156
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
1157
0
    *allocator = _PyObject_Arena;
1158
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1159
0
}
1160
1161
void
1162
PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)
1163
0
{
1164
0
    PyMutex_Lock(&ALLOCATORS_MUTEX);
1165
0
    _PyObject_Arena = *allocator;
1166
0
    PyMutex_Unlock(&ALLOCATORS_MUTEX);
1167
0
}
1168
1169
1170
/* Note that there is a possible, but very unlikely, race in any place
1171
 * below where we call one of the allocator functions.  We access two
1172
 * fields in each case:  "malloc", etc. and "ctx".
1173
 *
1174
 * It is unlikely that the allocator will be changed while one of those
1175
 * calls is happening, much less in that very narrow window.
1176
 * Furthermore, the likelihood of a race is drastically reduced by the
1177
 * fact that the allocator may not be changed after runtime init
1178
 * (except with a wrapper).
1179
 *
1180
 * With the above in mind, we currently don't worry about locking
1181
 * around these uses of the runtime-global allocators state. */
1182
1183
1184
/*************************/
1185
/* the "arena" allocator */
1186
/*************************/
1187
1188
void *
1189
_PyObject_VirtualAlloc(size_t size)
1190
32.9k
{
1191
32.9k
    size_t alloc_size = _pymalloc_virtual_alloc_size(size);
1192
32.9k
    if (alloc_size == 0 && size != 0) {
1193
0
        return NULL;
1194
0
    }
1195
32.9k
    return _PyObject_Arena.alloc(_PyObject_Arena.ctx, alloc_size);
1196
32.9k
}
1197
1198
void
1199
_PyObject_VirtualFree(void *obj, size_t size)
1200
32.8k
{
1201
32.8k
    size_t alloc_size = _pymalloc_virtual_alloc_size(size);
1202
32.8k
    assert(alloc_size != 0 || size == 0);
1203
32.8k
    _PyObject_Arena.free(_PyObject_Arena.ctx, obj, alloc_size);
1204
32.8k
}
1205
1206
1207
/***********************/
1208
/* the "raw" allocator */
1209
/***********************/
1210
1211
void *
1212
PyMem_RawMalloc(size_t size)
1213
175M
{
1214
    /*
1215
     * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
1216
     * Most python internals blindly use a signed Py_ssize_t to track
1217
     * things without checking for overflows or negatives.
1218
     * As size_t is unsigned, checking for size < 0 is not required.
1219
     */
1220
175M
    if (size > (size_t)PY_SSIZE_T_MAX)
1221
0
        return NULL;
1222
175M
    return _PyMem_Raw.malloc(_PyMem_Raw.ctx, size);
1223
175M
}
1224
1225
void *
1226
PyMem_RawCalloc(size_t nelem, size_t elsize)
1227
182k
{
1228
    /* see PyMem_RawMalloc() */
1229
182k
    if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize)
1230
0
        return NULL;
1231
182k
    return _PyMem_Raw.calloc(_PyMem_Raw.ctx, nelem, elsize);
1232
182k
}
1233
1234
void*
1235
PyMem_RawRealloc(void *ptr, size_t new_size)
1236
9.77M
{
1237
    /* see PyMem_RawMalloc() */
1238
9.77M
    if (new_size > (size_t)PY_SSIZE_T_MAX)
1239
0
        return NULL;
1240
9.77M
    return _PyMem_Raw.realloc(_PyMem_Raw.ctx, ptr, new_size);
1241
9.77M
}
1242
1243
void PyMem_RawFree(void *ptr)
1244
175M
{
1245
175M
    _PyMem_Raw.free(_PyMem_Raw.ctx, ptr);
1246
175M
}
1247
1248
1249
/***********************/
1250
/* the "mem" allocator */
1251
/***********************/
1252
1253
void *
1254
PyMem_Malloc(size_t size)
1255
196M
{
1256
    /* see PyMem_RawMalloc() */
1257
196M
    if (size > (size_t)PY_SSIZE_T_MAX)
1258
0
        return NULL;
1259
196M
    OBJECT_STAT_INC_COND(allocations512, size < 512);
1260
196M
    OBJECT_STAT_INC_COND(allocations4k, size >= 512 && size < 4094);
1261
196M
    OBJECT_STAT_INC_COND(allocations_big, size >= 4094);
1262
196M
    OBJECT_STAT_INC(allocations);
1263
196M
    return _PyMem.malloc(_PyMem.ctx, size);
1264
196M
}
1265
1266
void *
1267
PyMem_Calloc(size_t nelem, size_t elsize)
1268
45.3M
{
1269
    /* see PyMem_RawMalloc() */
1270
45.3M
    if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize)
1271
0
        return NULL;
1272
45.3M
    OBJECT_STAT_INC_COND(allocations512, elsize < 512);
1273
45.3M
    OBJECT_STAT_INC_COND(allocations4k, elsize >= 512 && elsize < 4094);
1274
45.3M
    OBJECT_STAT_INC_COND(allocations_big, elsize >= 4094);
1275
45.3M
    OBJECT_STAT_INC(allocations);
1276
45.3M
    return _PyMem.calloc(_PyMem.ctx, nelem, elsize);
1277
45.3M
}
1278
1279
void *
1280
PyMem_Realloc(void *ptr, size_t new_size)
1281
237M
{
1282
    /* see PyMem_RawMalloc() */
1283
237M
    if (new_size > (size_t)PY_SSIZE_T_MAX)
1284
0
        return NULL;
1285
237M
    return _PyMem.realloc(_PyMem.ctx, ptr, new_size);
1286
237M
}
1287
1288
void
1289
PyMem_Free(void *ptr)
1290
499M
{
1291
499M
    OBJECT_STAT_INC(frees);
1292
499M
    _PyMem.free(_PyMem.ctx, ptr);
1293
499M
}
1294
1295
1296
/***************************/
1297
/* pymem utility functions */
1298
/***************************/
1299
1300
wchar_t*
1301
_PyMem_RawWcsdup(const wchar_t *str)
1302
1.48k
{
1303
1.48k
    assert(str != NULL);
1304
1305
1.48k
    size_t len = wcslen(str);
1306
1.48k
    if (len > (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) {
1307
0
        return NULL;
1308
0
    }
1309
1310
1.48k
    size_t size = (len + 1) * sizeof(wchar_t);
1311
1.48k
    wchar_t *str2 = PyMem_RawMalloc(size);
1312
1.48k
    if (str2 == NULL) {
1313
0
        return NULL;
1314
0
    }
1315
1316
1.48k
    memcpy(str2, str, size);
1317
1.48k
    return str2;
1318
1.48k
}
1319
1320
char *
1321
_PyMem_RawStrdup(const char *str)
1322
111
{
1323
111
    assert(str != NULL);
1324
111
    size_t size = strlen(str) + 1;
1325
111
    char *copy = PyMem_RawMalloc(size);
1326
111
    if (copy == NULL) {
1327
0
        return NULL;
1328
0
    }
1329
111
    memcpy(copy, str, size);
1330
111
    return copy;
1331
111
}
1332
1333
char *
1334
_PyMem_Strdup(const char *str)
1335
14
{
1336
14
    assert(str != NULL);
1337
14
    size_t size = strlen(str) + 1;
1338
14
    char *copy = PyMem_Malloc(size);
1339
14
    if (copy == NULL) {
1340
0
        return NULL;
1341
0
    }
1342
14
    memcpy(copy, str, size);
1343
14
    return copy;
1344
14
}
1345
1346
/***********************************************/
1347
/* Delayed freeing support for Py_GIL_DISABLED */
1348
/***********************************************/
1349
1350
// So that sizeof(struct _mem_work_chunk) is 4096 bytes on 64-bit platforms.
1351
#define WORK_ITEMS_PER_CHUNK 254
1352
1353
// A pointer to be freed once the QSBR read sequence reaches qsbr_goal.
1354
struct _mem_work_item {
1355
    uintptr_t ptr; // lowest bit tagged 1 for objects freed with PyObject_Free
1356
    uint64_t qsbr_goal;
1357
};
1358
1359
// A fixed-size buffer of pointers to be freed
1360
struct _mem_work_chunk {
1361
    // Linked list node of chunks in queue
1362
    struct llist_node node;
1363
1364
    Py_ssize_t rd_idx;  // index of next item to read
1365
    Py_ssize_t wr_idx;  // index of next item to write
1366
    struct _mem_work_item array[WORK_ITEMS_PER_CHUNK];
1367
};
1368
1369
static int
1370
work_item_should_decref(uintptr_t ptr)
1371
1.28M
{
1372
1.28M
    return ptr & 0x01;
1373
1.28M
}
1374
1375
static void
1376
free_work_item(uintptr_t ptr, delayed_dealloc_cb cb, void *state)
1377
1.28M
{
1378
1.28M
    if (work_item_should_decref(ptr)) {
1379
0
        PyObject *obj = (PyObject *)(ptr - 1);
1380
#ifdef Py_GIL_DISABLED
1381
        if (cb == NULL) {
1382
            assert(!_PyInterpreterState_GET()->stoptheworld.world_stopped);
1383
            Py_DECREF(obj);
1384
            return;
1385
        }
1386
        assert(_PyInterpreterState_GET()->stoptheworld.world_stopped);
1387
        if (_Py_IsImmortal(obj)) {
1388
            // The object may have become immortal after it was queued.
1389
            return;
1390
        }
1391
        Py_ssize_t refcount = _Py_ExplicitMergeRefcount(obj, -1);
1392
        if (refcount == 0) {
1393
            cb(obj, state);
1394
        }
1395
#else
1396
0
        Py_DECREF(obj);
1397
0
#endif
1398
0
    }
1399
1.28M
    else {
1400
1.28M
        PyMem_Free((void *)ptr);
1401
1.28M
    }
1402
1.28M
}
1403
1404
1405
#ifdef Py_GIL_DISABLED
1406
1407
// For deferred advance on free: the number of deferred items before advancing
1408
// the write sequence.  This is based on WORK_ITEMS_PER_CHUNK.  We ideally
1409
// want to process a chunk before it overflows.
1410
#define QSBR_DEFERRED_LIMIT 127
1411
1412
// If the deferred memory exceeds 1 MiB, advance the write sequence.  This
1413
// helps limit memory usage due to QSBR delaying frees too long.
1414
#define QSBR_FREE_MEM_LIMIT 1024*1024
1415
1416
// Return true if the global write sequence should be advanced for a deferred
1417
// memory free.
1418
static bool
1419
should_advance_qsbr_for_free(struct _qsbr_thread_state *qsbr, size_t size)
1420
{
1421
    if (size > QSBR_FREE_MEM_LIMIT) {
1422
        qsbr->deferred_count = 0;
1423
        qsbr->deferred_memory = 0;
1424
        qsbr->should_process = true;
1425
        return true;
1426
    }
1427
    qsbr->deferred_count++;
1428
    qsbr->deferred_memory += size;
1429
    if (qsbr->deferred_count > QSBR_DEFERRED_LIMIT ||
1430
            qsbr->deferred_memory > QSBR_FREE_MEM_LIMIT) {
1431
        qsbr->deferred_count = 0;
1432
        qsbr->deferred_memory = 0;
1433
        qsbr->should_process = true;
1434
        return true;
1435
    }
1436
    return false;
1437
}
1438
#endif
1439
1440
static void
1441
free_delayed(uintptr_t ptr, size_t size)
1442
1.28M
{
1443
1.28M
#ifndef Py_GIL_DISABLED
1444
1.28M
    free_work_item(ptr, NULL, NULL);
1445
#else
1446
    PyInterpreterState *interp = _PyInterpreterState_GET();
1447
    if (_PyInterpreterState_GetFinalizing(interp) != NULL ||
1448
        interp->stoptheworld.world_stopped)
1449
    {
1450
        // Free immediately during interpreter shutdown or if the world is
1451
        // stopped.
1452
        assert(!interp->stoptheworld.world_stopped || !work_item_should_decref(ptr));
1453
        free_work_item(ptr, NULL, NULL);
1454
        return;
1455
    }
1456
1457
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
1458
    struct llist_node *head = &tstate->mem_free_queue;
1459
1460
    struct _mem_work_chunk *buf = NULL;
1461
    if (!llist_empty(head)) {
1462
        // Try to re-use the last buffer
1463
        buf = llist_data(head->prev, struct _mem_work_chunk, node);
1464
        if (buf->wr_idx == WORK_ITEMS_PER_CHUNK) {
1465
            // already full
1466
            buf = NULL;
1467
        }
1468
    }
1469
1470
    if (buf == NULL) {
1471
        buf = PyMem_Calloc(1, sizeof(*buf));
1472
        if (buf != NULL) {
1473
            llist_insert_tail(head, &buf->node);
1474
        }
1475
    }
1476
1477
    if (buf == NULL) {
1478
        // failed to allocate a buffer, free immediately
1479
        PyObject *to_dealloc = NULL;
1480
        _PyEval_StopTheWorld(tstate->base.interp);
1481
        if (work_item_should_decref(ptr)) {
1482
            PyObject *obj = (PyObject *)(ptr - 1);
1483
            if (!_Py_IsImmortal(obj)) {
1484
                Py_ssize_t refcount = _Py_ExplicitMergeRefcount(obj, -1);
1485
                if (refcount == 0) {
1486
                    to_dealloc = obj;
1487
                }
1488
            }
1489
        }
1490
        else {
1491
            PyMem_Free((void *)ptr);
1492
        }
1493
        _PyEval_StartTheWorld(tstate->base.interp);
1494
        if (to_dealloc != NULL) {
1495
            _Py_Dealloc(to_dealloc);
1496
        }
1497
        return;
1498
    }
1499
1500
    assert(buf != NULL && buf->wr_idx < WORK_ITEMS_PER_CHUNK);
1501
    uint64_t seq;
1502
    if (should_advance_qsbr_for_free(tstate->qsbr, size)) {
1503
        seq = _Py_qsbr_advance(tstate->qsbr->shared);
1504
    }
1505
    else {
1506
        seq = _Py_qsbr_shared_next(tstate->qsbr->shared);
1507
    }
1508
    buf->array[buf->wr_idx].ptr = ptr;
1509
    buf->array[buf->wr_idx].qsbr_goal = seq;
1510
    buf->wr_idx++;
1511
1512
    if (buf->wr_idx == WORK_ITEMS_PER_CHUNK) {
1513
        // Normally the processing of delayed items is done from the eval
1514
        // breaker.  Processing here is a safety measure to ensure too much
1515
        // work does not accumulate.
1516
        _PyMem_ProcessDelayed((PyThreadState *)tstate);
1517
    }
1518
#endif
1519
1.28M
}
1520
1521
void
1522
_PyMem_FreeDelayed(void *ptr, size_t size)
1523
1.28M
{
1524
1.28M
    assert(!((uintptr_t)ptr & 0x01));
1525
1.28M
    if (ptr != NULL) {
1526
1.28M
        free_delayed((uintptr_t)ptr, size);
1527
1.28M
    }
1528
1.28M
}
1529
1530
#ifdef Py_GIL_DISABLED
1531
void
1532
_PyObject_XDecRefDelayed(PyObject *ptr)
1533
{
1534
    assert(!((uintptr_t)ptr & 0x01));
1535
    if (ptr != NULL && !_Py_IsImmortal(ptr)) {
1536
        // We use 0 as the size since we don't have an easy way to know the
1537
        // actual size.  If we are freeing many objects, the write sequence
1538
        // will be advanced due to QSBR_DEFERRED_LIMIT.
1539
        free_delayed(((uintptr_t)ptr)|0x01, 0);
1540
    }
1541
}
1542
#endif
1543
1544
#ifdef Py_GIL_DISABLED
1545
void
1546
_PyObject_XSetRefDelayed(PyObject **ptr, PyObject *value)
1547
{
1548
    PyObject *old = *ptr;
1549
    FT_ATOMIC_STORE_PTR_RELEASE(*ptr, value);
1550
    _PyObject_XDecRefDelayed(old);
1551
}
1552
#endif
1553
1554
static struct _mem_work_chunk *
1555
work_queue_first(struct llist_node *head)
1556
0
{
1557
0
    return llist_data(head->next, struct _mem_work_chunk, node);
1558
0
}
1559
1560
static void
1561
process_queue(struct llist_node *head, _PyThreadStateImpl *tstate,
1562
              bool keep_empty, delayed_dealloc_cb cb, void *state)
1563
0
{
1564
0
    while (!llist_empty(head)) {
1565
0
        struct _mem_work_chunk *buf = work_queue_first(head);
1566
1567
0
        if (buf->rd_idx < buf->wr_idx) {
1568
0
            struct _mem_work_item *item = &buf->array[buf->rd_idx];
1569
0
            if (!_Py_qsbr_poll(tstate->qsbr, item->qsbr_goal)) {
1570
0
                return;
1571
0
            }
1572
1573
0
            buf->rd_idx++;
1574
            // NB: free_work_item may re-enter or execute arbitrary code
1575
0
            free_work_item(item->ptr, cb, state);
1576
0
            continue;
1577
0
        }
1578
1579
0
        assert(buf->rd_idx == buf->wr_idx);
1580
0
        if (keep_empty && buf->node.next == head) {
1581
            // Keep the last buffer in the queue to reduce re-allocations
1582
0
            buf->rd_idx = buf->wr_idx = 0;
1583
0
            return;
1584
0
        }
1585
1586
0
        llist_remove(&buf->node);
1587
0
        PyMem_Free(buf);
1588
0
    }
1589
0
}
1590
1591
static void
1592
process_interp_queue(struct _Py_mem_interp_free_queue *queue,
1593
                     _PyThreadStateImpl *tstate, delayed_dealloc_cb cb,
1594
                     void *state)
1595
0
{
1596
0
    assert(PyMutex_IsLocked(&queue->mutex));
1597
0
    process_queue(&queue->head, tstate, false, cb, state);
1598
1599
0
    int more_work = !llist_empty(&queue->head);
1600
0
    _Py_atomic_store_int_relaxed(&queue->has_work, more_work);
1601
0
}
1602
1603
static void
1604
maybe_process_interp_queue(struct _Py_mem_interp_free_queue *queue,
1605
                           _PyThreadStateImpl *tstate, delayed_dealloc_cb cb,
1606
                           void *state)
1607
0
{
1608
0
    if (!_Py_atomic_load_int_relaxed(&queue->has_work)) {
1609
0
        return;
1610
0
    }
1611
1612
    // Try to acquire the lock, but don't block if it's already held.
1613
0
    if (_PyMutex_LockTimed(&queue->mutex, 0, 0) == PY_LOCK_ACQUIRED) {
1614
0
        process_interp_queue(queue, tstate, cb, state);
1615
0
        PyMutex_Unlock(&queue->mutex);
1616
0
    }
1617
0
}
1618
1619
void
1620
_PyMem_ProcessDelayed(PyThreadState *tstate)
1621
0
{
1622
0
    PyInterpreterState *interp = tstate->interp;
1623
0
    _PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
1624
1625
0
    tstate_impl->qsbr->should_process = false;
1626
1627
    // Process thread-local work
1628
0
    process_queue(&tstate_impl->mem_free_queue, tstate_impl, true, NULL, NULL);
1629
1630
    // Process shared interpreter work
1631
0
    maybe_process_interp_queue(&interp->mem_free_queue, tstate_impl, NULL, NULL);
1632
0
}
1633
1634
void
1635
_PyMem_ProcessDelayedNoDealloc(PyThreadState *tstate, delayed_dealloc_cb cb, void *state)
1636
0
{
1637
0
    PyInterpreterState *interp = tstate->interp;
1638
0
    _PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
1639
1640
    // Process thread-local work
1641
0
    process_queue(&tstate_impl->mem_free_queue, tstate_impl, true, cb, state);
1642
1643
    // Process shared interpreter work
1644
0
    maybe_process_interp_queue(&interp->mem_free_queue, tstate_impl, cb, state);
1645
0
}
1646
1647
void
1648
_PyMem_AbandonDelayed(PyThreadState *tstate)
1649
0
{
1650
0
    PyInterpreterState *interp = tstate->interp;
1651
0
    struct llist_node *queue = &((_PyThreadStateImpl *)tstate)->mem_free_queue;
1652
1653
0
    if (llist_empty(queue)) {
1654
0
        return;
1655
0
    }
1656
1657
    // Check if the queue contains one empty buffer
1658
0
    struct _mem_work_chunk *buf = work_queue_first(queue);
1659
0
    if (buf->rd_idx == buf->wr_idx) {
1660
0
        llist_remove(&buf->node);
1661
0
        PyMem_Free(buf);
1662
0
        assert(llist_empty(queue));
1663
0
        return;
1664
0
    }
1665
1666
0
    PyMutex_Lock(&interp->mem_free_queue.mutex);
1667
1668
    // Merge the thread's work queue into the interpreter's work queue.
1669
0
    llist_concat(&interp->mem_free_queue.head, queue);
1670
1671
    // Process the merged queue now (see gh-130794).
1672
0
    _PyThreadStateImpl *this_tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
1673
0
    process_interp_queue(&interp->mem_free_queue, this_tstate, NULL, NULL);
1674
1675
0
    PyMutex_Unlock(&interp->mem_free_queue.mutex);
1676
1677
0
    assert(llist_empty(queue));  // the thread's queue is now empty
1678
0
}
1679
1680
void
1681
_PyMem_FiniDelayed(PyInterpreterState *interp)
1682
0
{
1683
0
    struct llist_node *head = &interp->mem_free_queue.head;
1684
0
    while (!llist_empty(head)) {
1685
0
        struct _mem_work_chunk *buf = work_queue_first(head);
1686
1687
0
        if (buf->rd_idx < buf->wr_idx) {
1688
            // Free the remaining items immediately. There should be no other
1689
            // threads accessing the memory at this point during shutdown.
1690
0
            struct _mem_work_item *item = &buf->array[buf->rd_idx];
1691
0
            buf->rd_idx++;
1692
            // NB: free_work_item may re-enter or execute arbitrary code
1693
0
            free_work_item(item->ptr, NULL, NULL);
1694
0
            continue;
1695
0
        }
1696
1697
0
        llist_remove(&buf->node);
1698
0
        PyMem_Free(buf);
1699
0
    }
1700
0
}
1701
1702
/**************************/
1703
/* the "object" allocator */
1704
/**************************/
1705
1706
void *
1707
PyObject_Malloc(size_t size)
1708
1.50G
{
1709
    /* see PyMem_RawMalloc() */
1710
1.50G
    if (size > (size_t)PY_SSIZE_T_MAX)
1711
0
        return NULL;
1712
1.50G
    OBJECT_STAT_INC_COND(allocations512, size < 512);
1713
1.50G
    OBJECT_STAT_INC_COND(allocations4k, size >= 512 && size < 4094);
1714
1.50G
    OBJECT_STAT_INC_COND(allocations_big, size >= 4094);
1715
1.50G
    OBJECT_STAT_INC(allocations);
1716
1.50G
    return _PyObject.malloc(_PyObject.ctx, size);
1717
1.50G
}
1718
1719
void *
1720
PyObject_Calloc(size_t nelem, size_t elsize)
1721
0
{
1722
    /* see PyMem_RawMalloc() */
1723
0
    if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize)
1724
0
        return NULL;
1725
0
    OBJECT_STAT_INC_COND(allocations512, elsize < 512);
1726
0
    OBJECT_STAT_INC_COND(allocations4k, elsize >= 512 && elsize < 4094);
1727
0
    OBJECT_STAT_INC_COND(allocations_big, elsize >= 4094);
1728
0
    OBJECT_STAT_INC(allocations);
1729
0
    return _PyObject.calloc(_PyObject.ctx, nelem, elsize);
1730
0
}
1731
1732
void *
1733
PyObject_Realloc(void *ptr, size_t new_size)
1734
61.1M
{
1735
    /* see PyMem_RawMalloc() */
1736
61.1M
    if (new_size > (size_t)PY_SSIZE_T_MAX)
1737
0
        return NULL;
1738
61.1M
    return _PyObject.realloc(_PyObject.ctx, ptr, new_size);
1739
61.1M
}
1740
1741
void
1742
PyObject_Free(void *ptr)
1743
1.49G
{
1744
1.49G
    OBJECT_STAT_INC(frees);
1745
1.49G
    _PyObject.free(_PyObject.ctx, ptr);
1746
1.49G
}
1747
1748
1749
/* Use __builtin_expect() where available to reduce overhead of
1750
   the valgrind checks */
1751
#if (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2))) && defined(__OPTIMIZE__)
1752
12.1G
#  define UNLIKELY(value) __builtin_expect((value), 0)
1753
5.52G
#  define LIKELY(value) __builtin_expect((value), 1)
1754
#else
1755
#  define UNLIKELY(value) (value)
1756
#  define LIKELY(value) (value)
1757
#endif
1758
1759
#ifdef WITH_PYMALLOC
1760
1761
#ifdef WITH_VALGRIND
1762
#include <valgrind/valgrind.h>
1763
1764
/* -1 indicates that we haven't checked that we're running on valgrind yet. */
1765
static int running_on_valgrind = -1;
1766
#endif
1767
1768
typedef struct _obmalloc_state OMState;
1769
1770
/* obmalloc state for main interpreter and shared by all interpreters without
1771
 * their own obmalloc state.  By not explicitly initializing this structure, it
1772
 * will be allocated in the BSS which is a small performance win.  The radix
1773
 * tree arrays are fairly large but are sparsely used.  */
1774
static struct _obmalloc_state obmalloc_state_main;
1775
static bool obmalloc_state_initialized;
1776
1777
static inline int
1778
has_own_state(PyInterpreterState *interp)
1779
0
{
1780
0
    return (_Py_IsMainInterpreter(interp) ||
1781
0
            !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC) ||
1782
0
            _Py_IsMainInterpreterFinalizing(interp));
1783
0
}
1784
1785
static inline OMState *
1786
get_state(void)
1787
4.11G
{
1788
4.11G
    PyInterpreterState *interp = _PyInterpreterState_GET();
1789
4.11G
    assert(interp->obmalloc != NULL); // otherwise not initialized or freed
1790
4.11G
    return interp->obmalloc;
1791
4.11G
}
1792
1793
// These macros all rely on a local "state" variable.
1794
2.00G
#define usedpools (state->pools.used)
1795
3.69M
#define allarenas (state->mgmt.arenas)
1796
353
#define maxarenas (state->mgmt.maxarenas)
1797
43.6k
#define unused_arena_objects (state->mgmt.unused_arena_objects)
1798
30.9M
#define usable_arenas (state->mgmt.usable_arenas)
1799
21.5M
#define nfp2lasta (state->mgmt.nfp2lasta)
1800
27.4k
#define narenas_currently_allocated (state->mgmt.narenas_currently_allocated)
1801
8.98k
#define ntimes_arena_allocated (state->mgmt.ntimes_arena_allocated)
1802
10.1k
#define narenas_highwater (state->mgmt.narenas_highwater)
1803
349M
#define raw_allocated_blocks (state->mgmt.raw_allocated_blocks)
1804
1805
#ifdef WITH_MIMALLOC
1806
static bool count_blocks(
1807
    const mi_heap_t* heap, const mi_heap_area_t* area,
1808
    void* block, size_t block_size, void* allocated_blocks)
1809
0
{
1810
0
    *(size_t *)allocated_blocks += area->used;
1811
0
    return 1;
1812
0
}
1813
1814
static Py_ssize_t
1815
get_mimalloc_allocated_blocks(PyInterpreterState *interp)
1816
0
{
1817
0
    size_t allocated_blocks = 0;
1818
#ifdef Py_GIL_DISABLED
1819
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, t) {
1820
        _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)t;
1821
        for (int i = 0; i < _Py_MIMALLOC_HEAP_COUNT; i++) {
1822
            mi_heap_t *heap = &tstate->mimalloc.heaps[i];
1823
            mi_heap_visit_blocks(heap, false, &count_blocks, &allocated_blocks);
1824
        }
1825
    }
1826
1827
    mi_abandoned_pool_t *pool = &interp->mimalloc.abandoned_pool;
1828
    for (uint8_t tag = 0; tag < _Py_MIMALLOC_HEAP_COUNT; tag++) {
1829
        _mi_abandoned_pool_visit_blocks(pool, tag, false, &count_blocks,
1830
                                        &allocated_blocks);
1831
    }
1832
#else
1833
    // TODO(sgross): this only counts the current thread's blocks.
1834
0
    mi_heap_t *heap = mi_heap_get_default();
1835
0
    mi_heap_visit_blocks(heap, false, &count_blocks, &allocated_blocks);
1836
0
#endif
1837
0
    return allocated_blocks;
1838
0
}
1839
#endif
1840
1841
Py_ssize_t
1842
_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp)
1843
0
{
1844
0
#ifdef WITH_MIMALLOC
1845
0
    if (_PyMem_MimallocEnabled()) {
1846
0
        return get_mimalloc_allocated_blocks(interp);
1847
0
    }
1848
0
#endif
1849
1850
#ifdef Py_DEBUG
1851
    assert(has_own_state(interp));
1852
#else
1853
0
    if (!has_own_state(interp)) {
1854
0
        _Py_FatalErrorFunc(__func__,
1855
0
                           "the interpreter doesn't have its own allocator");
1856
0
    }
1857
0
#endif
1858
0
    OMState *state = interp->obmalloc;
1859
1860
0
    if (state == NULL) {
1861
0
        return 0;
1862
0
    }
1863
1864
0
    Py_ssize_t n = raw_allocated_blocks;
1865
    /* add up allocated blocks for used pools */
1866
0
    for (uint i = 0; i < maxarenas; ++i) {
1867
        /* Skip arenas which are not allocated. */
1868
0
        if (allarenas[i].address == 0) {
1869
0
            continue;
1870
0
        }
1871
1872
0
        uintptr_t base = (uintptr_t)_Py_ALIGN_UP(allarenas[i].address, POOL_SIZE);
1873
1874
        /* visit every pool in the arena */
1875
0
        assert(base <= (uintptr_t) allarenas[i].pool_address);
1876
0
        for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) {
1877
0
            poolp p = (poolp)base;
1878
0
            n += p->ref.count;
1879
0
        }
1880
0
    }
1881
0
    return n;
1882
0
}
1883
1884
static void free_obmalloc_arenas(PyInterpreterState *interp);
1885
1886
void
1887
_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *interp)
1888
0
{
1889
0
#ifdef WITH_MIMALLOC
1890
0
    if (_PyMem_MimallocEnabled()) {
1891
0
        Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp);
1892
0
        interp->runtime->obmalloc.interpreter_leaks += leaked;
1893
0
        return;
1894
0
    }
1895
0
#endif
1896
0
    if (has_own_state(interp) && interp->obmalloc != NULL) {
1897
0
        Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp);
1898
0
        assert(has_own_state(interp) || leaked == 0);
1899
0
        interp->runtime->obmalloc.interpreter_leaks += leaked;
1900
0
        if (_PyMem_obmalloc_state_on_heap(interp) && leaked == 0) {
1901
            // free the obmalloc arenas and radix tree nodes.  If leaked > 0
1902
            // then some of the memory allocated by obmalloc has not been
1903
            // freed.  It might be safe to free the arenas in that case but
1904
            // it's possible that extension modules are still using that
1905
            // memory.  So, it is safer to not free and to leak.  Perhaps there
1906
            // should be warning when this happens.  It should be possible to
1907
            // use a tool like "-fsanitize=address" to track down these leaks.
1908
0
            free_obmalloc_arenas(interp);
1909
0
        }
1910
0
    }
1911
0
}
1912
1913
static Py_ssize_t get_num_global_allocated_blocks(_PyRuntimeState *);
1914
1915
/* We preserve the number of blocks leaked during runtime finalization,
1916
   so they can be reported if the runtime is initialized again. */
1917
// XXX We don't lose any information by dropping this,
1918
// so we should consider doing so.
1919
static Py_ssize_t last_final_leaks = 0;
1920
1921
void
1922
_Py_FinalizeAllocatedBlocks(_PyRuntimeState *runtime)
1923
0
{
1924
0
    last_final_leaks = get_num_global_allocated_blocks(runtime);
1925
0
    runtime->obmalloc.interpreter_leaks = 0;
1926
0
}
1927
1928
static Py_ssize_t
1929
get_num_global_allocated_blocks(_PyRuntimeState *runtime)
1930
0
{
1931
0
    Py_ssize_t total = 0;
1932
0
    if (_PyRuntimeState_GetFinalizing(runtime) != NULL) {
1933
0
        PyInterpreterState *interp = _PyInterpreterState_Main();
1934
0
        if (interp == NULL) {
1935
            /* We are at the very end of runtime finalization.
1936
               We can't rely on finalizing->interp since that thread
1937
               state is probably already freed, so we don't worry
1938
               about it. */
1939
0
            assert(PyInterpreterState_Head() == NULL);
1940
0
        }
1941
0
        else {
1942
0
            assert(interp != NULL);
1943
            /* It is probably the last interpreter but not necessarily. */
1944
0
            assert(PyInterpreterState_Next(interp) == NULL);
1945
0
            total += _PyInterpreterState_GetAllocatedBlocks(interp);
1946
0
        }
1947
0
    }
1948
0
    else {
1949
0
        _PyEval_StopTheWorldAll(&_PyRuntime);
1950
0
        HEAD_LOCK(runtime);
1951
0
        PyInterpreterState *interp = PyInterpreterState_Head();
1952
0
        assert(interp != NULL);
1953
#ifdef Py_DEBUG
1954
        int got_main = 0;
1955
#endif
1956
0
        for (; interp != NULL; interp = PyInterpreterState_Next(interp)) {
1957
#ifdef Py_DEBUG
1958
            if (_Py_IsMainInterpreter(interp)) {
1959
                assert(!got_main);
1960
                got_main = 1;
1961
                assert(has_own_state(interp));
1962
            }
1963
#endif
1964
0
            if (has_own_state(interp)) {
1965
0
                total += _PyInterpreterState_GetAllocatedBlocks(interp);
1966
0
            }
1967
0
        }
1968
0
        HEAD_UNLOCK(runtime);
1969
0
        _PyEval_StartTheWorldAll(&_PyRuntime);
1970
#ifdef Py_DEBUG
1971
        assert(got_main);
1972
#endif
1973
0
    }
1974
0
    total += runtime->obmalloc.interpreter_leaks;
1975
0
    total += last_final_leaks;
1976
0
    return total;
1977
0
}
1978
1979
Py_ssize_t
1980
_Py_GetGlobalAllocatedBlocks(void)
1981
0
{
1982
0
    return get_num_global_allocated_blocks(&_PyRuntime);
1983
0
}
1984
1985
#if WITH_PYMALLOC_RADIX_TREE
1986
/*==========================================================================*/
1987
/* radix tree for tracking arena usage. */
1988
1989
6.11G
#define arena_map_root (state->usage.arena_map_root)
1990
#ifdef USE_INTERIOR_NODES
1991
37
#define arena_map_mid_count (state->usage.arena_map_mid_count)
1992
37
#define arena_map_bot_count (state->usage.arena_map_bot_count)
1993
#endif
1994
1995
/* Return a pointer to a bottom tree node, return NULL if it doesn't exist or
1996
 * it cannot be created */
1997
static inline Py_ALWAYS_INLINE arena_map_bot_t *
1998
arena_map_get(OMState *state, pymem_block *p, int create)
1999
2.09G
{
2000
2.09G
#ifdef USE_INTERIOR_NODES
2001
    /* sanity check that IGNORE_BITS is correct */
2002
2.09G
    assert(HIGH_BITS(p) == HIGH_BITS(&arena_map_root));
2003
2.09G
    int i1 = MAP_TOP_INDEX(p);
2004
2.09G
    if (arena_map_root.ptrs[i1] == NULL) {
2005
37
        if (!create) {
2006
0
            return NULL;
2007
0
        }
2008
37
        arena_map_mid_t *n = PyMem_RawCalloc(1, sizeof(arena_map_mid_t));
2009
37
        if (n == NULL) {
2010
0
            return NULL;
2011
0
        }
2012
37
        arena_map_root.ptrs[i1] = n;
2013
37
        arena_map_mid_count++;
2014
37
    }
2015
2.09G
    int i2 = MAP_MID_INDEX(p);
2016
2.09G
    if (arena_map_root.ptrs[i1]->ptrs[i2] == NULL) {
2017
184M
        if (!create) {
2018
184M
            return NULL;
2019
184M
        }
2020
37
        arena_map_bot_t *n = PyMem_RawCalloc(1, sizeof(arena_map_bot_t));
2021
37
        if (n == NULL) {
2022
0
            return NULL;
2023
0
        }
2024
37
        arena_map_root.ptrs[i1]->ptrs[i2] = n;
2025
37
        arena_map_bot_count++;
2026
37
    }
2027
1.91G
    return arena_map_root.ptrs[i1]->ptrs[i2];
2028
#else
2029
    return &arena_map_root;
2030
#endif
2031
2.09G
}
2032
2033
2034
/* The radix tree only tracks arenas.  So, for 16 MiB arenas, we throw
2035
 * away 24 bits of the address.  That reduces the space requirement of
2036
 * the tree compared to similar radix tree page-map schemes.  In
2037
 * exchange for slashing the space requirement, it needs more
2038
 * computation to check an address.
2039
 *
2040
 * Tracking coverage is done by "ideal" arena address.  It is easier to
2041
 * explain in decimal so let's say that the arena size is 100 bytes.
2042
 * Then, ideal addresses are 100, 200, 300, etc.  For checking if a
2043
 * pointer address is inside an actual arena, we have to check two ideal
2044
 * arena addresses.  E.g. if pointer is 357, we need to check 200 and
2045
 * 300.  In the rare case that an arena is aligned in the ideal way
2046
 * (e.g. base address of arena is 200) then we only have to check one
2047
 * ideal address.
2048
 *
2049
 * The tree nodes for 200 and 300 both store the address of arena.
2050
 * There are two cases: the arena starts at a lower ideal arena and
2051
 * extends to this one, or the arena starts in this arena and extends to
2052
 * the next ideal arena.  The tail_lo and tail_hi members correspond to
2053
 * these two cases.
2054
 */
2055
2056
2057
/* mark or unmark addresses covered by arena */
2058
static int
2059
arena_map_mark_used(OMState *state, uintptr_t arena_base, int is_used)
2060
17.3k
{
2061
    /* sanity check that IGNORE_BITS is correct */
2062
17.3k
    assert(HIGH_BITS(arena_base) == HIGH_BITS(&arena_map_root));
2063
17.3k
    arena_map_bot_t *n_hi = arena_map_get(
2064
17.3k
            state, (pymem_block *)arena_base, is_used);
2065
17.3k
    if (n_hi == NULL) {
2066
0
        assert(is_used); /* otherwise node should already exist */
2067
0
        return 0; /* failed to allocate space for node */
2068
0
    }
2069
17.3k
    int i3 = MAP_BOT_INDEX((pymem_block *)arena_base);
2070
17.3k
    int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK);
2071
17.3k
    if (tail == 0) {
2072
        /* is ideal arena address */
2073
66
        n_hi->arenas[i3].tail_hi = is_used ? -1 : 0;
2074
66
    }
2075
17.2k
    else {
2076
        /* arena_base address is not ideal (aligned to arena size) and
2077
         * so it potentially covers two MAP_BOT nodes.  Get the MAP_BOT node
2078
         * for the next arena.  Note that it might be in different MAP_TOP
2079
         * and MAP_MID nodes as well so we need to call arena_map_get()
2080
         * again (do the full tree traversal).
2081
         */
2082
17.2k
        n_hi->arenas[i3].tail_hi = is_used ? tail : 0;
2083
17.2k
        uintptr_t arena_base_next = arena_base + ARENA_SIZE;
2084
        /* If arena_base is a legit arena address, so is arena_base_next - 1
2085
         * (last address in arena).  If arena_base_next overflows then it
2086
         * must overflow to 0.  However, that would mean arena_base was
2087
         * "ideal" and we should not be in this case. */
2088
17.2k
        assert(arena_base < arena_base_next);
2089
17.2k
        arena_map_bot_t *n_lo = arena_map_get(
2090
17.2k
                state, (pymem_block *)arena_base_next, is_used);
2091
17.2k
        if (n_lo == NULL) {
2092
0
            assert(is_used); /* otherwise should already exist */
2093
0
            n_hi->arenas[i3].tail_hi = 0;
2094
0
            return 0; /* failed to allocate space for node */
2095
0
        }
2096
17.2k
        int i3_next = MAP_BOT_INDEX(arena_base_next);
2097
17.2k
        n_lo->arenas[i3_next].tail_lo = is_used ? tail : 0;
2098
17.2k
    }
2099
17.3k
    return 1;
2100
17.3k
}
2101
2102
/* Return true if 'p' is a pointer inside an obmalloc arena.
2103
 * _PyObject_Free() calls this so it needs to be very fast. */
2104
static int
2105
arena_map_is_used(OMState *state, pymem_block *p)
2106
2.09G
{
2107
2.09G
    arena_map_bot_t *n = arena_map_get(state, p, 0);
2108
2.09G
    if (n == NULL) {
2109
184M
        return 0;
2110
184M
    }
2111
1.91G
    int i3 = MAP_BOT_INDEX(p);
2112
    /* ARENA_BITS must be < 32 so that the tail is a non-negative int32_t. */
2113
1.91G
    int32_t hi = n->arenas[i3].tail_hi;
2114
1.91G
    int32_t lo = n->arenas[i3].tail_lo;
2115
1.91G
    int32_t tail = (int32_t)(AS_UINT(p) & ARENA_SIZE_MASK);
2116
1.91G
    return (tail < lo) || (tail >= hi && hi != 0);
2117
2.09G
}
2118
2119
/* end of radix tree logic */
2120
/*==========================================================================*/
2121
#endif /* WITH_PYMALLOC_RADIX_TREE */
2122
2123
2124
/* Allocate a new arena.  If we run out of memory, return NULL.  Else
2125
 * allocate a new arena, and return the address of an arena_object
2126
 * describing the new arena.  It's expected that the caller will set
2127
 * `usable_arenas` to the return value.
2128
 */
2129
static struct arena_object*
2130
new_arena(OMState *state)
2131
8.98k
{
2132
8.98k
    struct arena_object* arenaobj;
2133
8.98k
    uint excess;        /* number of bytes above pool alignment */
2134
8.98k
    void *address;
2135
2136
8.98k
    int debug_stats = _PyRuntime.obmalloc.dump_debug_stats;
2137
8.98k
    if (debug_stats == -1) {
2138
37
        const char *opt = Py_GETENV("PYTHONMALLOCSTATS");
2139
37
        debug_stats = (opt != NULL && *opt != '\0');
2140
37
        _PyRuntime.obmalloc.dump_debug_stats = debug_stats;
2141
37
    }
2142
8.98k
    if (debug_stats) {
2143
0
        _PyObject_DebugMallocStats(stderr);
2144
0
    }
2145
2146
8.98k
    if (unused_arena_objects == NULL) {
2147
65
        uint i;
2148
65
        uint numarenas;
2149
65
        size_t nbytes;
2150
2151
        /* Double the number of arena objects on each allocation.
2152
         * Note that it's possible for `numarenas` to overflow.
2153
         */
2154
65
        numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
2155
65
        if (numarenas <= maxarenas)
2156
0
            return NULL;                /* overflow */
2157
#if SIZEOF_SIZE_T <= SIZEOF_INT
2158
        if (numarenas > SIZE_MAX / sizeof(*allarenas))
2159
            return NULL;                /* overflow */
2160
#endif
2161
65
        nbytes = numarenas * sizeof(*allarenas);
2162
65
        arenaobj = (struct arena_object *)PyMem_RawRealloc(allarenas, nbytes);
2163
65
        if (arenaobj == NULL)
2164
0
            return NULL;
2165
65
        allarenas = arenaobj;
2166
2167
        /* We might need to fix pointers that were copied.  However,
2168
         * new_arena only gets called when all the pages in the
2169
         * previous arenas are full.  Thus, there are *no* pointers
2170
         * into the old array. Thus, we don't have to worry about
2171
         * invalid pointers.  Just to be sure, some asserts:
2172
         */
2173
65
        assert(usable_arenas == NULL);
2174
65
        assert(unused_arena_objects == NULL);
2175
2176
        /* Put the new arenas on the unused_arena_objects list. */
2177
1.74k
        for (i = maxarenas; i < numarenas; ++i) {
2178
1.68k
            allarenas[i].address = 0;              /* mark as unassociated */
2179
1.68k
            allarenas[i].nextarena = i < numarenas - 1 ?
2180
1.68k
                                        &allarenas[i+1] : NULL;
2181
1.68k
        }
2182
2183
        /* Update globals. */
2184
65
        unused_arena_objects = &allarenas[maxarenas];
2185
65
        maxarenas = numarenas;
2186
65
    }
2187
2188
    /* Take the next available arena object off the head of the list. */
2189
8.98k
    assert(unused_arena_objects != NULL);
2190
8.98k
    arenaobj = unused_arena_objects;
2191
8.98k
    unused_arena_objects = arenaobj->nextarena;
2192
8.98k
    assert(arenaobj->address == 0);
2193
8.98k
    address = _PyObject_Arena.alloc(_PyObject_Arena.ctx, ARENA_SIZE);
2194
8.98k
#if WITH_PYMALLOC_RADIX_TREE
2195
8.98k
    if (address != NULL) {
2196
8.98k
        if (!arena_map_mark_used(state, (uintptr_t)address, 1)) {
2197
            /* marking arena in radix tree failed, abort */
2198
0
            _PyObject_Arena.free(_PyObject_Arena.ctx, address, ARENA_SIZE);
2199
0
            address = NULL;
2200
0
        }
2201
8.98k
    }
2202
8.98k
#endif
2203
8.98k
    if (address == NULL) {
2204
        /* The allocation failed: return NULL after putting the
2205
         * arenaobj back.
2206
         */
2207
0
        arenaobj->nextarena = unused_arena_objects;
2208
0
        unused_arena_objects = arenaobj;
2209
0
        return NULL;
2210
0
    }
2211
8.98k
    arenaobj->address = (uintptr_t)address;
2212
2213
8.98k
    ++narenas_currently_allocated;
2214
8.98k
    ++ntimes_arena_allocated;
2215
8.98k
    if (narenas_currently_allocated > narenas_highwater)
2216
1.11k
        narenas_highwater = narenas_currently_allocated;
2217
8.98k
    arenaobj->freepools = NULL;
2218
    /* pool_address <- first pool-aligned address in the arena
2219
       nfreepools <- number of whole pools that fit after alignment */
2220
8.98k
    arenaobj->pool_address = (pymem_block*)arenaobj->address;
2221
8.98k
    arenaobj->nfreepools = MAX_POOLS_IN_ARENA;
2222
8.98k
    excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
2223
8.98k
    if (excess != 0) {
2224
8.10k
        --arenaobj->nfreepools;
2225
8.10k
        arenaobj->pool_address += POOL_SIZE - excess;
2226
8.10k
    }
2227
8.98k
    arenaobj->ntotalpools = arenaobj->nfreepools;
2228
2229
8.98k
    return arenaobj;
2230
8.98k
}
2231
2232
2233
2234
#if WITH_PYMALLOC_RADIX_TREE
2235
/* Return true if and only if P is an address that was allocated by
2236
   pymalloc.  When the radix tree is used, 'poolp' is unused.
2237
 */
2238
static bool
2239
address_in_range(OMState *state, void *p, poolp Py_UNUSED(pool))
2240
2.09G
{
2241
2.09G
    return arena_map_is_used(state, p);
2242
2.09G
}
2243
#else
2244
/*
2245
address_in_range(P, POOL)
2246
2247
Return true if and only if P is an address that was allocated by pymalloc.
2248
POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
2249
(the caller is asked to compute this because the macro expands POOL more than
2250
once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
2251
variable and pass the latter to the macro; because address_in_range is
2252
called on every alloc/realloc/free, micro-efficiency is important here).
2253
2254
Tricky:  Let B be the arena base address associated with the pool, B =
2255
arenas[(POOL)->arenaindex].address.  Then P belongs to the arena if and only if
2256
2257
    B <= P < B + ARENA_SIZE
2258
2259
Subtracting B throughout, this is true iff
2260
2261
    0 <= P-B < ARENA_SIZE
2262
2263
By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
2264
2265
Obscure:  A PyMem "free memory" function can call the pymalloc free or realloc
2266
before the first arena has been allocated.  `arenas` is still NULL in that
2267
case.  We're relying on that maxarenas is also 0 in that case, so that
2268
(POOL)->arenaindex < maxarenas  must be false, saving us from trying to index
2269
into a NULL arenas.
2270
2271
Details:  given P and POOL, the arena_object corresponding to P is AO =
2272
arenas[(POOL)->arenaindex].  Suppose obmalloc controls P.  Then (barring wild
2273
stores, etc), POOL is the correct address of P's pool, AO.address is the
2274
correct base address of the pool's arena, and P must be within ARENA_SIZE of
2275
AO.address.  In addition, AO.address is not 0 (no arena can start at address 0
2276
(NULL)).  Therefore address_in_range correctly reports that obmalloc
2277
controls P.
2278
2279
Now suppose obmalloc does not control P (e.g., P was obtained via a direct
2280
call to the system malloc() or realloc()).  (POOL)->arenaindex may be anything
2281
in this case -- it may even be uninitialized trash.  If the trash arenaindex
2282
is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
2283
control P.
2284
2285
Else arenaindex is < maxarena, and AO is read up.  If AO corresponds to an
2286
allocated arena, obmalloc controls all the memory in slice AO.address :
2287
AO.address+ARENA_SIZE.  By case assumption, P is not controlled by obmalloc,
2288
so P doesn't lie in that slice, so the macro correctly reports that P is not
2289
controlled by obmalloc.
2290
2291
Finally, if P is not controlled by obmalloc and AO corresponds to an unused
2292
arena_object (one not currently associated with an allocated arena),
2293
AO.address is 0, and the second test in the macro reduces to:
2294
2295
    P < ARENA_SIZE
2296
2297
If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
2298
that P is not controlled by obmalloc.  However, if P < ARENA_SIZE, this part
2299
of the test still passes, and the third clause (AO.address != 0) is necessary
2300
to get the correct result:  AO.address is 0 in this case, so the macro
2301
correctly reports that P is not controlled by obmalloc (despite that P lies in
2302
slice AO.address : AO.address + ARENA_SIZE).
2303
2304
Note:  The third (AO.address != 0) clause was added in Python 2.5.  Before
2305
2.5, arenas were never free()'ed, and an arenaindex < maxarena always
2306
corresponded to a currently-allocated arena, so the "P is not controlled by
2307
obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
2308
was impossible.
2309
2310
Note that the logic is excruciating, and reading up possibly uninitialized
2311
memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
2312
creates problems for some memory debuggers.  The overwhelming advantage is
2313
that this test determines whether an arbitrary address is controlled by
2314
obmalloc in a small constant time, independent of the number of arenas
2315
obmalloc controls.  Since this test is needed at every entry point, it's
2316
extremely desirable that it be this fast.
2317
*/
2318
2319
static bool _Py_NO_SANITIZE_ADDRESS
2320
            _Py_NO_SANITIZE_THREAD
2321
            _Py_NO_SANITIZE_MEMORY
2322
address_in_range(OMState *state, void *p, poolp pool)
2323
{
2324
    // Since address_in_range may be reading from memory which was not allocated
2325
    // by Python, it is important that pool->arenaindex is read only once, as
2326
    // another thread may be concurrently modifying the value without holding
2327
    // the GIL. The following dance forces the compiler to read pool->arenaindex
2328
    // only once.
2329
    uint arenaindex = *((volatile uint *)&pool->arenaindex);
2330
    return arenaindex < maxarenas &&
2331
        (uintptr_t)p - allarenas[arenaindex].address < ARENA_SIZE &&
2332
        allarenas[arenaindex].address != 0;
2333
}
2334
2335
#endif /* !WITH_PYMALLOC_RADIX_TREE */
2336
2337
/*==========================================================================*/
2338
2339
// Called when freelist is exhausted.  Extend the freelist if there is
2340
// space for a block.  Otherwise, remove this pool from usedpools.
2341
static void
2342
pymalloc_pool_extend(poolp pool, uint size)
2343
399M
{
2344
399M
    if (UNLIKELY(pool->nextoffset <= pool->maxnextoffset)) {
2345
        /* There is room for another block. */
2346
239M
        pool->freeblock = (pymem_block*)pool + pool->nextoffset;
2347
239M
        pool->nextoffset += INDEX2SIZE(size);
2348
239M
        *(pymem_block **)(pool->freeblock) = NULL;
2349
239M
        return;
2350
239M
    }
2351
2352
    /* Pool is full, unlink from used pools. */
2353
160M
    poolp next;
2354
160M
    next = pool->nextpool;
2355
160M
    pool = pool->prevpool;
2356
160M
    next->prevpool = pool;
2357
160M
    pool->nextpool = next;
2358
160M
}
2359
2360
/* called when pymalloc_alloc can not allocate a block from usedpool.
2361
 * This function takes new pool and allocate a block from it.
2362
 */
2363
static void*
2364
allocate_from_new_pool(OMState *state, uint size)
2365
3.16M
{
2366
    /* There isn't a pool of the right size class immediately
2367
     * available:  use a free pool.
2368
     */
2369
3.16M
    if (UNLIKELY(usable_arenas == NULL)) {
2370
        /* No arena has a free pool:  allocate a new arena. */
2371
#ifdef WITH_MEMORY_LIMITS
2372
        if (narenas_currently_allocated >= MAX_ARENAS) {
2373
            return NULL;
2374
        }
2375
#endif
2376
8.98k
        usable_arenas = new_arena(state);
2377
8.98k
        if (usable_arenas == NULL) {
2378
0
            return NULL;
2379
0
        }
2380
8.98k
        usable_arenas->nextarena = usable_arenas->prevarena = NULL;
2381
8.98k
        assert(nfp2lasta[usable_arenas->nfreepools] == NULL);
2382
8.98k
        nfp2lasta[usable_arenas->nfreepools] = usable_arenas;
2383
8.98k
    }
2384
3.16M
    assert(usable_arenas->address != 0);
2385
2386
    /* This arena already had the smallest nfreepools value, so decreasing
2387
     * nfreepools doesn't change that, and we don't need to rearrange the
2388
     * usable_arenas list.  However, if the arena becomes wholly allocated,
2389
     * we need to remove its arena_object from usable_arenas.
2390
     */
2391
3.16M
    assert(usable_arenas->nfreepools > 0);
2392
3.16M
    if (nfp2lasta[usable_arenas->nfreepools] == usable_arenas) {
2393
        /* It's the last of this size, so there won't be any. */
2394
3.14M
        nfp2lasta[usable_arenas->nfreepools] = NULL;
2395
3.14M
    }
2396
    /* If any free pools will remain, it will be the new smallest. */
2397
3.16M
    if (usable_arenas->nfreepools > 1) {
2398
3.03M
        assert(nfp2lasta[usable_arenas->nfreepools - 1] == NULL);
2399
3.03M
        nfp2lasta[usable_arenas->nfreepools - 1] = usable_arenas;
2400
3.03M
    }
2401
2402
    /* Try to get a cached free pool. */
2403
3.16M
    poolp pool = usable_arenas->freepools;
2404
3.16M
    if (LIKELY(pool != NULL)) {
2405
        /* Unlink from cached pools. */
2406
2.60M
        usable_arenas->freepools = pool->nextpool;
2407
2.60M
        usable_arenas->nfreepools--;
2408
2.60M
        if (UNLIKELY(usable_arenas->nfreepools == 0)) {
2409
            /* Wholly allocated:  remove. */
2410
120k
            assert(usable_arenas->freepools == NULL);
2411
120k
            assert(usable_arenas->nextarena == NULL ||
2412
120k
                   usable_arenas->nextarena->prevarena ==
2413
120k
                   usable_arenas);
2414
120k
            usable_arenas = usable_arenas->nextarena;
2415
120k
            if (usable_arenas != NULL) {
2416
111k
                usable_arenas->prevarena = NULL;
2417
111k
                assert(usable_arenas->address != 0);
2418
111k
            }
2419
120k
        }
2420
2.48M
        else {
2421
            /* nfreepools > 0:  it must be that freepools
2422
             * isn't NULL, or that we haven't yet carved
2423
             * off all the arena's pools for the first
2424
             * time.
2425
             */
2426
2.48M
            assert(usable_arenas->freepools != NULL ||
2427
2.48M
                   usable_arenas->pool_address <=
2428
2.48M
                   (pymem_block*)usable_arenas->address +
2429
2.48M
                       ARENA_SIZE - POOL_SIZE);
2430
2.48M
        }
2431
2.60M
    }
2432
559k
    else {
2433
        /* Carve off a new pool. */
2434
559k
        assert(usable_arenas->nfreepools > 0);
2435
559k
        assert(usable_arenas->freepools == NULL);
2436
559k
        pool = (poolp)usable_arenas->pool_address;
2437
559k
        assert((pymem_block*)pool <= (pymem_block*)usable_arenas->address +
2438
559k
                                 ARENA_SIZE - POOL_SIZE);
2439
559k
        pool->arenaindex = (uint)(usable_arenas - allarenas);
2440
559k
        assert(&allarenas[pool->arenaindex] == usable_arenas);
2441
559k
        pool->szidx = DUMMY_SIZE_IDX;
2442
559k
        usable_arenas->pool_address += POOL_SIZE;
2443
559k
        --usable_arenas->nfreepools;
2444
2445
559k
        if (usable_arenas->nfreepools == 0) {
2446
8.74k
            assert(usable_arenas->nextarena == NULL ||
2447
8.74k
                   usable_arenas->nextarena->prevarena ==
2448
8.74k
                   usable_arenas);
2449
            /* Unlink the arena:  it is completely allocated. */
2450
8.74k
            usable_arenas = usable_arenas->nextarena;
2451
8.74k
            if (usable_arenas != NULL) {
2452
276
                usable_arenas->prevarena = NULL;
2453
276
                assert(usable_arenas->address != 0);
2454
276
            }
2455
8.74k
        }
2456
559k
    }
2457
2458
    /* Frontlink to used pools. */
2459
3.16M
    pymem_block *bp;
2460
3.16M
    poolp next = usedpools[size + size]; /* == prev */
2461
3.16M
    pool->nextpool = next;
2462
3.16M
    pool->prevpool = next;
2463
3.16M
    next->nextpool = pool;
2464
3.16M
    next->prevpool = pool;
2465
3.16M
    pool->ref.count = 1;
2466
3.16M
    if (pool->szidx == size) {
2467
        /* Luckily, this pool last contained blocks
2468
         * of the same size class, so its header
2469
         * and free list are already initialized.
2470
         */
2471
2.03M
        bp = pool->freeblock;
2472
2.03M
        assert(bp != NULL);
2473
2.03M
        pool->freeblock = *(pymem_block **)bp;
2474
2.03M
        return bp;
2475
2.03M
    }
2476
    /*
2477
     * Initialize the pool header, set up the free list to
2478
     * contain just the second block, and return the first
2479
     * block.
2480
     */
2481
1.12M
    pool->szidx = size;
2482
1.12M
    size = INDEX2SIZE(size);
2483
1.12M
    bp = (pymem_block *)pool + POOL_OVERHEAD;
2484
1.12M
    pool->nextoffset = POOL_OVERHEAD + (size << 1);
2485
1.12M
    pool->maxnextoffset = POOL_SIZE - size;
2486
1.12M
    pool->freeblock = bp + size;
2487
1.12M
    *(pymem_block **)(pool->freeblock) = NULL;
2488
1.12M
    return bp;
2489
3.16M
}
2490
2491
/* pymalloc allocator
2492
2493
   Return a pointer to newly allocated memory if pymalloc allocated memory.
2494
2495
   Return NULL if pymalloc failed to allocate the memory block: on bigger
2496
   requests, on error in the code below (as a last chance to serve the request)
2497
   or when the max memory limit has been reached.
2498
*/
2499
static inline void*
2500
pymalloc_alloc(OMState *state, void *Py_UNUSED(ctx), size_t nbytes)
2501
2.01G
{
2502
#ifdef WITH_VALGRIND
2503
    if (UNLIKELY(running_on_valgrind == -1)) {
2504
        running_on_valgrind = RUNNING_ON_VALGRIND;
2505
    }
2506
    if (UNLIKELY(running_on_valgrind)) {
2507
        return NULL;
2508
    }
2509
#endif
2510
2511
2.01G
    if (UNLIKELY(nbytes == 0)) {
2512
53.1k
        return NULL;
2513
53.1k
    }
2514
2.01G
    if (UNLIKELY(nbytes > SMALL_REQUEST_THRESHOLD)) {
2515
174M
        return NULL;
2516
174M
    }
2517
2518
1.83G
    uint size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
2519
1.83G
    poolp pool = usedpools[size + size];
2520
1.83G
    pymem_block *bp;
2521
2522
1.83G
    if (LIKELY(pool != pool->nextpool)) {
2523
        /*
2524
         * There is a used pool for this size class.
2525
         * Pick up the head block of its free list.
2526
         */
2527
1.83G
        ++pool->ref.count;
2528
1.83G
        bp = pool->freeblock;
2529
1.83G
        assert(bp != NULL);
2530
2531
1.83G
        if (UNLIKELY((pool->freeblock = *(pymem_block **)bp) == NULL)) {
2532
            // Reached the end of the free list, try to extend it.
2533
399M
            pymalloc_pool_extend(pool, size);
2534
399M
        }
2535
1.83G
    }
2536
3.16M
    else {
2537
        /* There isn't a pool of the right size class immediately
2538
         * available:  use a free pool.
2539
         */
2540
3.16M
        bp = allocate_from_new_pool(state, size);
2541
3.16M
    }
2542
2543
1.83G
    return (void *)bp;
2544
2.01G
}
2545
2546
2547
void *
2548
_PyObject_Malloc(void *ctx, size_t nbytes)
2549
1.96G
{
2550
1.96G
    OMState *state = get_state();
2551
1.96G
    void* ptr = pymalloc_alloc(state, ctx, nbytes);
2552
1.96G
    if (LIKELY(ptr != NULL)) {
2553
1.79G
        return ptr;
2554
1.79G
    }
2555
2556
174M
    ptr = PyMem_RawMalloc(nbytes);
2557
174M
    if (ptr != NULL) {
2558
174M
        raw_allocated_blocks++;
2559
174M
    }
2560
174M
    return ptr;
2561
1.96G
}
2562
2563
2564
void *
2565
_PyObject_Calloc(void *ctx, size_t nelem, size_t elsize)
2566
45.3M
{
2567
45.3M
    assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize);
2568
45.3M
    size_t nbytes = nelem * elsize;
2569
2570
45.3M
    OMState *state = get_state();
2571
45.3M
    void* ptr = pymalloc_alloc(state, ctx, nbytes);
2572
45.3M
    if (LIKELY(ptr != NULL)) {
2573
45.1M
        memset(ptr, 0, nbytes);
2574
45.1M
        return ptr;
2575
45.1M
    }
2576
2577
181k
    ptr = PyMem_RawCalloc(nelem, elsize);
2578
181k
    if (ptr != NULL) {
2579
181k
        raw_allocated_blocks++;
2580
181k
    }
2581
181k
    return ptr;
2582
45.3M
}
2583
2584
2585
static void
2586
insert_to_usedpool(OMState *state, poolp pool)
2587
160M
{
2588
160M
    assert(pool->ref.count > 0);            /* else the pool is empty */
2589
2590
160M
    uint size = pool->szidx;
2591
160M
    poolp next = usedpools[size + size];
2592
160M
    poolp prev = next->prevpool;
2593
2594
    /* insert pool before next:   prev <-> pool <-> next */
2595
160M
    pool->nextpool = next;
2596
160M
    pool->prevpool = prev;
2597
160M
    next->prevpool = pool;
2598
160M
    prev->nextpool = pool;
2599
160M
}
2600
2601
static void
2602
insert_to_freepool(OMState *state, poolp pool)
2603
3.12M
{
2604
3.12M
    poolp next = pool->nextpool;
2605
3.12M
    poolp prev = pool->prevpool;
2606
3.12M
    next->prevpool = prev;
2607
3.12M
    prev->nextpool = next;
2608
2609
    /* Link the pool to freepools.  This is a singly-linked
2610
     * list, and pool->prevpool isn't used there.
2611
     */
2612
3.12M
    struct arena_object *ao = &allarenas[pool->arenaindex];
2613
3.12M
    pool->nextpool = ao->freepools;
2614
3.12M
    ao->freepools = pool;
2615
3.12M
    uint nf = ao->nfreepools;
2616
    /* If this is the rightmost arena with this number of free pools,
2617
     * nfp2lasta[nf] needs to change.  Caution:  if nf is 0, there
2618
     * are no arenas in usable_arenas with that value.
2619
     */
2620
3.12M
    struct arena_object* lastnf = nfp2lasta[nf];
2621
3.12M
    assert((nf == 0 && lastnf == NULL) ||
2622
3.12M
           (nf > 0 &&
2623
3.12M
            lastnf != NULL &&
2624
3.12M
            lastnf->nfreepools == nf &&
2625
3.12M
            (lastnf->nextarena == NULL ||
2626
3.12M
             nf < lastnf->nextarena->nfreepools)));
2627
3.12M
    if (lastnf == ao) {  /* it is the rightmost */
2628
2.91M
        struct arena_object* p = ao->prevarena;
2629
2.91M
        nfp2lasta[nf] = (p != NULL && p->nfreepools == nf) ? p : NULL;
2630
2.91M
    }
2631
3.12M
    ao->nfreepools = ++nf;
2632
2633
    /* All the rest is arena management.  We just freed
2634
     * a pool, and there are 4 cases for arena mgmt:
2635
     * 1. If all the pools are free, return the arena to
2636
     *    the system free().  Except if this is the last
2637
     *    arena in the list, keep it to avoid thrashing:
2638
     *    keeping one wholly free arena in the list avoids
2639
     *    pathological cases where a simple loop would
2640
     *    otherwise provoke needing to allocate and free an
2641
     *    arena on every iteration.  See bpo-37257.
2642
     * 2. If this is the only free pool in the arena,
2643
     *    add the arena back to the `usable_arenas` list.
2644
     * 3. If the "next" arena has a smaller count of free
2645
     *    pools, we have to "slide this arena right" to
2646
     *    restore that usable_arenas is sorted in order of
2647
     *    nfreepools.
2648
     * 4. Else there's nothing more to do.
2649
     */
2650
3.12M
    if (nf == ao->ntotalpools && ao->nextarena != NULL) {
2651
        /* Case 1.  First unlink ao from usable_arenas.
2652
         */
2653
8.34k
        assert(ao->prevarena == NULL ||
2654
8.34k
               ao->prevarena->address != 0);
2655
8.34k
        assert(ao ->nextarena == NULL ||
2656
8.34k
               ao->nextarena->address != 0);
2657
2658
        /* Fix the pointer in the prevarena, or the
2659
         * usable_arenas pointer.
2660
         */
2661
8.34k
        if (ao->prevarena == NULL) {
2662
1.53k
            usable_arenas = ao->nextarena;
2663
1.53k
            assert(usable_arenas == NULL ||
2664
1.53k
                   usable_arenas->address != 0);
2665
1.53k
        }
2666
6.80k
        else {
2667
6.80k
            assert(ao->prevarena->nextarena == ao);
2668
6.80k
            ao->prevarena->nextarena =
2669
6.80k
                ao->nextarena;
2670
6.80k
        }
2671
        /* Fix the pointer in the nextarena. */
2672
8.34k
        if (ao->nextarena != NULL) {
2673
8.34k
            assert(ao->nextarena->prevarena == ao);
2674
8.34k
            ao->nextarena->prevarena =
2675
8.34k
                ao->prevarena;
2676
8.34k
        }
2677
        /* Record that this arena_object slot is
2678
         * available to be reused.
2679
         */
2680
8.34k
        ao->nextarena = unused_arena_objects;
2681
8.34k
        unused_arena_objects = ao;
2682
2683
8.34k
#if WITH_PYMALLOC_RADIX_TREE
2684
        /* mark arena region as not under control of obmalloc */
2685
8.34k
        arena_map_mark_used(state, ao->address, 0);
2686
8.34k
#endif
2687
2688
        /* Free the entire arena. */
2689
8.34k
        _PyObject_Arena.free(_PyObject_Arena.ctx,
2690
8.34k
                             (void *)ao->address, ARENA_SIZE);
2691
8.34k
        ao->address = 0;                        /* mark unassociated */
2692
8.34k
        --narenas_currently_allocated;
2693
2694
8.34k
        return;
2695
8.34k
    }
2696
2697
3.12M
    if (nf == 1) {
2698
        /* Case 2.  Put ao at the head of
2699
         * usable_arenas.  Note that because
2700
         * ao->nfreepools was 0 before, ao isn't
2701
         * currently on the usable_arenas list.
2702
         */
2703
128k
        ao->nextarena = usable_arenas;
2704
128k
        ao->prevarena = NULL;
2705
128k
        if (usable_arenas)
2706
119k
            usable_arenas->prevarena = ao;
2707
128k
        usable_arenas = ao;
2708
128k
        assert(usable_arenas->address != 0);
2709
128k
        if (nfp2lasta[1] == NULL) {
2710
124k
            nfp2lasta[1] = ao;
2711
124k
        }
2712
2713
128k
        return;
2714
128k
    }
2715
2716
    /* If this arena is now out of order, we need to keep
2717
     * the list sorted.  The list is kept sorted so that
2718
     * the "most full" arenas are used first, which allows
2719
     * the nearly empty arenas to be completely freed.  In
2720
     * a few un-scientific tests, it seems like this
2721
     * approach allowed a lot more memory to be freed.
2722
     */
2723
    /* If this is the only arena with nf, record that. */
2724
2.99M
    if (nfp2lasta[nf] == NULL) {
2725
2.88M
        nfp2lasta[nf] = ao;
2726
2.88M
    } /* else the rightmost with nf doesn't change */
2727
    /* If this was the rightmost of the old size, it remains in place. */
2728
2.99M
    if (ao == lastnf) {
2729
        /* Case 4.  Nothing to do. */
2730
2.91M
        return;
2731
2.91M
    }
2732
    /* If ao were the only arena in the list, the last block would have
2733
     * gotten us out.
2734
     */
2735
2.99M
    assert(ao->nextarena != NULL);
2736
2737
    /* Case 3:  We have to move the arena towards the end of the list,
2738
     * because it has more free pools than the arena to its right.  It needs
2739
     * to move to follow lastnf.
2740
     * First unlink ao from usable_arenas.
2741
     */
2742
81.3k
    if (ao->prevarena != NULL) {
2743
        /* ao isn't at the head of the list */
2744
64.0k
        assert(ao->prevarena->nextarena == ao);
2745
64.0k
        ao->prevarena->nextarena = ao->nextarena;
2746
64.0k
    }
2747
17.3k
    else {
2748
        /* ao is at the head of the list */
2749
17.3k
        assert(usable_arenas == ao);
2750
17.3k
        usable_arenas = ao->nextarena;
2751
17.3k
    }
2752
81.3k
    ao->nextarena->prevarena = ao->prevarena;
2753
    /* And insert after lastnf. */
2754
81.3k
    ao->prevarena = lastnf;
2755
81.3k
    ao->nextarena = lastnf->nextarena;
2756
81.3k
    if (ao->nextarena != NULL) {
2757
79.8k
        ao->nextarena->prevarena = ao;
2758
79.8k
    }
2759
81.3k
    lastnf->nextarena = ao;
2760
    /* Verify that the swaps worked. */
2761
81.3k
    assert(ao->nextarena == NULL || nf <= ao->nextarena->nfreepools);
2762
81.3k
    assert(ao->prevarena == NULL || nf > ao->prevarena->nfreepools);
2763
81.3k
    assert(ao->nextarena == NULL || ao->nextarena->prevarena == ao);
2764
81.3k
    assert((usable_arenas == ao && ao->prevarena == NULL)
2765
81.3k
           || ao->prevarena->nextarena == ao);
2766
81.3k
}
2767
2768
/* Free a memory block allocated by pymalloc_alloc().
2769
   Return 1 if it was freed.
2770
   Return 0 if the block was not allocated by pymalloc_alloc(). */
2771
static inline int
2772
pymalloc_free(OMState *state, void *Py_UNUSED(ctx), void *p)
2773
2.00G
{
2774
2.00G
    assert(p != NULL);
2775
2776
#ifdef WITH_VALGRIND
2777
    if (UNLIKELY(running_on_valgrind > 0)) {
2778
        return 0;
2779
    }
2780
#endif
2781
2782
2.00G
    poolp pool = POOL_ADDR(p);
2783
2.00G
    if (UNLIKELY(!address_in_range(state, p, pool))) {
2784
174M
        return 0;
2785
174M
    }
2786
    /* We allocated this address. */
2787
2788
    /* Link p to the start of the pool's freeblock list.  Since
2789
     * the pool had at least the p block outstanding, the pool
2790
     * wasn't empty (so it's already in a usedpools[] list, or
2791
     * was full and is in no list -- it's not in the freeblocks
2792
     * list in any case).
2793
     */
2794
2.00G
    assert(pool->ref.count > 0);            /* else it was empty */
2795
1.83G
    pymem_block *lastfree = pool->freeblock;
2796
1.83G
    *(pymem_block **)p = lastfree;
2797
1.83G
    pool->freeblock = (pymem_block *)p;
2798
1.83G
    pool->ref.count--;
2799
2800
1.83G
    if (UNLIKELY(lastfree == NULL)) {
2801
        /* Pool was full, so doesn't currently live in any list:
2802
         * link it to the front of the appropriate usedpools[] list.
2803
         * This mimics LRU pool usage for new allocations and
2804
         * targets optimal filling when several pools contain
2805
         * blocks of the same size class.
2806
         */
2807
160M
        insert_to_usedpool(state, pool);
2808
160M
        return 1;
2809
160M
    }
2810
2811
    /* freeblock wasn't NULL, so the pool wasn't full,
2812
     * and the pool is in a usedpools[] list.
2813
     */
2814
1.67G
    if (LIKELY(pool->ref.count != 0)) {
2815
        /* pool isn't empty:  leave it in usedpools */
2816
1.66G
        return 1;
2817
1.66G
    }
2818
2819
    /* Pool is now empty:  unlink from usedpools, and
2820
     * link to the front of freepools.  This ensures that
2821
     * previously freed pools will be allocated later
2822
     * (being not referenced, they are perhaps paged out).
2823
     */
2824
3.12M
    insert_to_freepool(state, pool);
2825
3.12M
    return 1;
2826
1.67G
}
2827
2828
2829
void
2830
_PyObject_Free(void *ctx, void *p)
2831
2.06G
{
2832
    /* PyObject_Free(NULL) has no effect */
2833
2.06G
    if (p == NULL) {
2834
52.9M
        return;
2835
52.9M
    }
2836
2837
2.00G
    OMState *state = get_state();
2838
2.00G
    if (UNLIKELY(!pymalloc_free(state, ctx, p))) {
2839
        /* pymalloc didn't allocate this address */
2840
174M
        PyMem_RawFree(p);
2841
174M
        raw_allocated_blocks--;
2842
174M
    }
2843
2.00G
}
2844
2845
2846
/* pymalloc realloc.
2847
2848
   If nbytes==0, then as the Python docs promise, we do not treat this like
2849
   free(p), and return a non-NULL result.
2850
2851
   Return 1 if pymalloc reallocated memory and wrote the new pointer into
2852
   newptr_p.
2853
2854
   Return 0 if pymalloc didn't allocated p. */
2855
static int
2856
pymalloc_realloc(OMState *state, void *ctx,
2857
                 void **newptr_p, void *p, size_t nbytes)
2858
91.2M
{
2859
91.2M
    void *bp;
2860
91.2M
    poolp pool;
2861
91.2M
    size_t size;
2862
2863
91.2M
    assert(p != NULL);
2864
2865
#ifdef WITH_VALGRIND
2866
    /* Treat running_on_valgrind == -1 the same as 0 */
2867
    if (UNLIKELY(running_on_valgrind > 0)) {
2868
        return 0;
2869
    }
2870
#endif
2871
2872
91.2M
    pool = POOL_ADDR(p);
2873
91.2M
    if (!address_in_range(state, p, pool)) {
2874
        /* pymalloc is not managing this block.
2875
2876
           If nbytes <= SMALL_REQUEST_THRESHOLD, it's tempting to try to take
2877
           over this block.  However, if we do, we need to copy the valid data
2878
           from the C-managed block to one of our blocks, and there's no
2879
           portable way to know how much of the memory space starting at p is
2880
           valid.
2881
2882
           As bug 1185883 pointed out the hard way, it's possible that the
2883
           C-managed block is "at the end" of allocated VM space, so that a
2884
           memory fault can occur if we try to copy nbytes bytes starting at p.
2885
           Instead we punt: let C continue to manage this block. */
2886
9.77M
        return 0;
2887
9.77M
    }
2888
2889
    /* pymalloc is in charge of this block */
2890
81.4M
    size = INDEX2SIZE(pool->szidx);
2891
81.4M
    if (nbytes <= size) {
2892
        /* The block is staying the same or shrinking.
2893
2894
           If it's shrinking, there's a tradeoff: it costs cycles to copy the
2895
           block to a smaller size class, but it wastes memory not to copy it.
2896
2897
           The compromise here is to copy on shrink only if at least 25% of
2898
           size can be shaved off. */
2899
50.9M
        if (4 * nbytes > 3 * size) {
2900
            /* It's the same, or shrinking and new/old > 3/4. */
2901
16.8M
            *newptr_p = p;
2902
16.8M
            return 1;
2903
16.8M
        }
2904
34.0M
        size = nbytes;
2905
34.0M
    }
2906
2907
64.6M
    bp = _PyObject_Malloc(ctx, nbytes);
2908
64.6M
    if (bp != NULL) {
2909
64.6M
        memcpy(bp, p, size);
2910
64.6M
        _PyObject_Free(ctx, p);
2911
64.6M
    }
2912
64.6M
    *newptr_p = bp;
2913
64.6M
    return 1;
2914
81.4M
}
2915
2916
2917
void *
2918
_PyObject_Realloc(void *ctx, void *ptr, size_t nbytes)
2919
298M
{
2920
298M
    void *ptr2;
2921
2922
298M
    if (ptr == NULL) {
2923
207M
        return _PyObject_Malloc(ctx, nbytes);
2924
207M
    }
2925
2926
91.2M
    OMState *state = get_state();
2927
91.2M
    if (pymalloc_realloc(state, ctx, &ptr2, ptr, nbytes)) {
2928
81.4M
        return ptr2;
2929
81.4M
    }
2930
2931
9.77M
    return PyMem_RawRealloc(ptr, nbytes);
2932
91.2M
}
2933
2934
#else   /* ! WITH_PYMALLOC */
2935
2936
/*==========================================================================*/
2937
/* pymalloc not enabled:  Redirect the entry points to malloc.  These will
2938
 * only be used by extensions that are compiled with pymalloc enabled. */
2939
2940
Py_ssize_t
2941
_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp))
2942
{
2943
    return 0;
2944
}
2945
2946
Py_ssize_t
2947
_Py_GetGlobalAllocatedBlocks(void)
2948
{
2949
    return 0;
2950
}
2951
2952
void
2953
_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp))
2954
{
2955
    return;
2956
}
2957
2958
void
2959
_Py_FinalizeAllocatedBlocks(_PyRuntimeState *Py_UNUSED(runtime))
2960
{
2961
    return;
2962
}
2963
2964
#endif /* WITH_PYMALLOC */
2965
2966
2967
/*==========================================================================*/
2968
/* A x-platform debugging allocator.  This doesn't manage memory directly,
2969
 * it wraps a real allocator, adding extra debugging info to the memory blocks.
2970
 */
2971
2972
/* Uncomment this define to add the "serialno" field */
2973
/* #define PYMEM_DEBUG_SERIALNO */
2974
2975
#ifdef PYMEM_DEBUG_SERIALNO
2976
static size_t serialno = 0;     /* incremented on each debug {m,re}alloc */
2977
2978
/* serialno is always incremented via calling this routine.  The point is
2979
 * to supply a single place to set a breakpoint.
2980
 */
2981
static void
2982
bumpserialno(void)
2983
{
2984
    ++serialno;
2985
}
2986
#endif
2987
2988
0
#define SST SIZEOF_SIZE_T
2989
2990
#ifdef PYMEM_DEBUG_SERIALNO
2991
#  define PYMEM_DEBUG_EXTRA_BYTES 4 * SST
2992
#else
2993
0
#  define PYMEM_DEBUG_EXTRA_BYTES 3 * SST
2994
#endif
2995
2996
/* Read sizeof(size_t) bytes at p as a big-endian size_t. */
2997
static size_t
2998
read_size_t(const void *p)
2999
0
{
3000
0
    const uint8_t *q = (const uint8_t *)p;
3001
0
    size_t result = *q++;
3002
0
    int i;
3003
3004
0
    for (i = SST; --i > 0; ++q)
3005
0
        result = (result << 8) | *q;
3006
0
    return result;
3007
0
}
3008
3009
/* Write n as a big-endian size_t, MSB at address p, LSB at
3010
 * p + sizeof(size_t) - 1.
3011
 */
3012
static void
3013
write_size_t(void *p, size_t n)
3014
0
{
3015
0
    uint8_t *q = (uint8_t *)p + SST - 1;
3016
0
    int i;
3017
3018
0
    for (i = SST; --i >= 0; --q) {
3019
0
        *q = (uint8_t)(n & 0xff);
3020
0
        n >>= 8;
3021
0
    }
3022
0
}
3023
3024
static void
3025
fill_mem_debug(debug_alloc_api_t *api, void *data, int c, size_t nbytes,
3026
               bool is_alloc)
3027
0
{
3028
#ifdef Py_GIL_DISABLED
3029
    if (api->api_id == 'o') {
3030
        // Don't overwrite the first few bytes of a PyObject allocation in the
3031
        // free-threaded build
3032
        _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
3033
        size_t debug_offset;
3034
        if (is_alloc) {
3035
            debug_offset = tstate->mimalloc.current_object_heap->debug_offset;
3036
        }
3037
        else {
3038
            char *alloc = (char *)data - 2*SST;  // start of the allocation
3039
            debug_offset = _mi_ptr_page(alloc)->debug_offset;
3040
        }
3041
        debug_offset -= 2*SST;  // account for pymalloc extra bytes
3042
        if (debug_offset < nbytes) {
3043
            memset((char *)data + debug_offset, c, nbytes - debug_offset);
3044
        }
3045
        return;
3046
    }
3047
#endif
3048
0
    memset(data, c, nbytes);
3049
0
}
3050
3051
/* Let S = sizeof(size_t).  The debug malloc asks for 4 * S extra bytes and
3052
   fills them with useful stuff, here calling the underlying malloc's result p:
3053
3054
p[0: S]
3055
    Number of bytes originally asked for.  This is a size_t, big-endian (easier
3056
    to read in a memory dump).
3057
p[S]
3058
    API ID.  See PEP 445.  This is a character, but seems undocumented.
3059
p[S+1: 2*S]
3060
    Copies of PYMEM_FORBIDDENBYTE.  Used to catch under- writes and reads.
3061
p[2*S: 2*S+n]
3062
    The requested memory, filled with copies of PYMEM_CLEANBYTE.
3063
    Used to catch reference to uninitialized memory.
3064
    &p[2*S] is returned.  Note that this is 8-byte aligned if pymalloc
3065
    handled the request itself.
3066
p[2*S+n: 2*S+n+S]
3067
    Copies of PYMEM_FORBIDDENBYTE.  Used to catch over- writes and reads.
3068
p[2*S+n+S: 2*S+n+2*S]
3069
    A serial number, incremented by 1 on each call to _PyMem_DebugMalloc
3070
    and _PyMem_DebugRealloc.
3071
    This is a big-endian size_t.
3072
    If "bad memory" is detected later, the serial number gives an
3073
    excellent way to set a breakpoint on the next run, to capture the
3074
    instant at which this block was passed out.
3075
3076
If PYMEM_DEBUG_SERIALNO is not defined (default), the debug malloc only asks
3077
for 3 * S extra bytes, and omits the last serialno field.
3078
*/
3079
3080
static void *
3081
_PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes)
3082
0
{
3083
0
    debug_alloc_api_t *api = (debug_alloc_api_t *)ctx;
3084
0
    uint8_t *p;           /* base address of malloc'ed pad block */
3085
0
    uint8_t *data;        /* p + 2*SST == pointer to data bytes */
3086
0
    uint8_t *tail;        /* data + nbytes == pointer to tail pad bytes */
3087
0
    size_t total;         /* nbytes + PYMEM_DEBUG_EXTRA_BYTES */
3088
3089
0
    if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) {
3090
        /* integer overflow: can't represent total as a Py_ssize_t */
3091
0
        return NULL;
3092
0
    }
3093
0
    total = nbytes + PYMEM_DEBUG_EXTRA_BYTES;
3094
3095
    /* Layout: [SSSS IFFF CCCC...CCCC FFFF NNNN]
3096
                ^--- p    ^--- data   ^--- tail
3097
       S: nbytes stored as size_t
3098
       I: API identifier (1 byte)
3099
       F: Forbidden bytes (size_t - 1 bytes before, size_t bytes after)
3100
       C: Clean bytes used later to store actual data
3101
       N: Serial number stored as size_t
3102
3103
       If PYMEM_DEBUG_SERIALNO is not defined (default), the last NNNN field
3104
       is omitted. */
3105
3106
0
    if (use_calloc) {
3107
0
        p = (uint8_t *)api->alloc.calloc(api->alloc.ctx, 1, total);
3108
0
    }
3109
0
    else {
3110
0
        p = (uint8_t *)api->alloc.malloc(api->alloc.ctx, total);
3111
0
    }
3112
0
    if (p == NULL) {
3113
0
        return NULL;
3114
0
    }
3115
0
    data = p + 2*SST;
3116
3117
#ifdef PYMEM_DEBUG_SERIALNO
3118
    bumpserialno();
3119
#endif
3120
3121
    /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */
3122
0
    write_size_t(p, nbytes);
3123
0
    p[SST] = (uint8_t)api->api_id;
3124
0
    memset(p + SST + 1, PYMEM_FORBIDDENBYTE, SST-1);
3125
3126
0
    if (nbytes > 0 && !use_calloc) {
3127
0
        fill_mem_debug(api, data, PYMEM_CLEANBYTE, nbytes, true);
3128
0
    }
3129
3130
    /* at tail, write pad (SST bytes) and serialno (SST bytes) */
3131
0
    tail = data + nbytes;
3132
0
    memset(tail, PYMEM_FORBIDDENBYTE, SST);
3133
#ifdef PYMEM_DEBUG_SERIALNO
3134
    write_size_t(tail + SST, serialno);
3135
#endif
3136
3137
0
    return data;
3138
0
}
3139
3140
void *
3141
_PyMem_DebugRawMalloc(void *ctx, size_t nbytes)
3142
0
{
3143
0
    return _PyMem_DebugRawAlloc(0, ctx, nbytes);
3144
0
}
3145
3146
void *
3147
_PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize)
3148
0
{
3149
0
    size_t nbytes;
3150
0
    assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize);
3151
0
    nbytes = nelem * elsize;
3152
0
    return _PyMem_DebugRawAlloc(1, ctx, nbytes);
3153
0
}
3154
3155
3156
/* The debug free first checks the 2*SST bytes on each end for sanity (in
3157
   particular, that the FORBIDDENBYTEs with the api ID are still intact).
3158
   Then fills the original bytes with PYMEM_DEADBYTE.
3159
   Then calls the underlying free.
3160
*/
3161
void
3162
_PyMem_DebugRawFree(void *ctx, void *p)
3163
0
{
3164
    /* PyMem_Free(NULL) has no effect */
3165
0
    if (p == NULL) {
3166
0
        return;
3167
0
    }
3168
3169
0
    debug_alloc_api_t *api = (debug_alloc_api_t *)ctx;
3170
0
    uint8_t *q = (uint8_t *)p - 2*SST;  /* address returned from malloc */
3171
0
    size_t nbytes;
3172
3173
0
    _PyMem_DebugCheckAddress(__func__, api->api_id, p);
3174
0
    nbytes = read_size_t(q);
3175
0
    nbytes += PYMEM_DEBUG_EXTRA_BYTES - 2*SST;
3176
0
    memset(q, PYMEM_DEADBYTE, 2*SST);
3177
0
    fill_mem_debug(api, p, PYMEM_DEADBYTE, nbytes, false);
3178
0
    api->alloc.free(api->alloc.ctx, q);
3179
0
}
3180
3181
3182
void *
3183
_PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
3184
0
{
3185
0
    if (p == NULL) {
3186
0
        return _PyMem_DebugRawAlloc(0, ctx, nbytes);
3187
0
    }
3188
3189
0
    debug_alloc_api_t *api = (debug_alloc_api_t *)ctx;
3190
0
    uint8_t *head;        /* base address of malloc'ed pad block */
3191
0
    uint8_t *data;        /* pointer to data bytes */
3192
0
    uint8_t *r;
3193
0
    uint8_t *tail;        /* data + nbytes == pointer to tail pad bytes */
3194
0
    size_t total;         /* 2 * SST + nbytes + 2 * SST */
3195
0
    size_t original_nbytes;
3196
0
#define ERASED_SIZE 64
3197
3198
0
    _PyMem_DebugCheckAddress(__func__, api->api_id, p);
3199
3200
0
    data = (uint8_t *)p;
3201
0
    head = data - 2*SST;
3202
0
    original_nbytes = read_size_t(head);
3203
0
    if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) {
3204
        /* integer overflow: can't represent total as a Py_ssize_t */
3205
0
        return NULL;
3206
0
    }
3207
0
    total = nbytes + PYMEM_DEBUG_EXTRA_BYTES;
3208
3209
0
    tail = data + original_nbytes;
3210
#ifdef PYMEM_DEBUG_SERIALNO
3211
    size_t block_serialno = read_size_t(tail + SST);
3212
#endif
3213
0
#ifndef Py_GIL_DISABLED
3214
    /* Mark the header, the trailer, ERASED_SIZE bytes at the begin and
3215
       ERASED_SIZE bytes at the end as dead and save the copy of erased bytes.
3216
     */
3217
0
    uint8_t save[2*ERASED_SIZE];  /* A copy of erased bytes. */
3218
0
    if (original_nbytes <= sizeof(save)) {
3219
0
        memcpy(save, data, original_nbytes);
3220
0
        memset(data - 2 * SST, PYMEM_DEADBYTE,
3221
0
               original_nbytes + PYMEM_DEBUG_EXTRA_BYTES);
3222
0
    }
3223
0
    else {
3224
0
        memcpy(save, data, ERASED_SIZE);
3225
0
        memset(head, PYMEM_DEADBYTE, ERASED_SIZE + 2 * SST);
3226
0
        memcpy(&save[ERASED_SIZE], tail - ERASED_SIZE, ERASED_SIZE);
3227
0
        memset(tail - ERASED_SIZE, PYMEM_DEADBYTE,
3228
0
               ERASED_SIZE + PYMEM_DEBUG_EXTRA_BYTES - 2 * SST);
3229
0
    }
3230
0
#endif
3231
3232
    /* Resize and add decorations. */
3233
0
    r = (uint8_t *)api->alloc.realloc(api->alloc.ctx, head, total);
3234
0
    if (r == NULL) {
3235
        /* if realloc() failed: rewrite header and footer which have
3236
           just been erased */
3237
0
        nbytes = original_nbytes;
3238
0
    }
3239
0
    else {
3240
0
        head = r;
3241
#ifdef PYMEM_DEBUG_SERIALNO
3242
        bumpserialno();
3243
        block_serialno = serialno;
3244
#endif
3245
0
    }
3246
0
    data = head + 2*SST;
3247
3248
0
    write_size_t(head, nbytes);
3249
0
    head[SST] = (uint8_t)api->api_id;
3250
0
    memset(head + SST + 1, PYMEM_FORBIDDENBYTE, SST-1);
3251
3252
0
    tail = data + nbytes;
3253
0
    memset(tail, PYMEM_FORBIDDENBYTE, SST);
3254
#ifdef PYMEM_DEBUG_SERIALNO
3255
    write_size_t(tail + SST, block_serialno);
3256
#endif
3257
3258
0
#ifndef Py_GIL_DISABLED
3259
    /* Restore saved bytes. */
3260
0
    if (original_nbytes <= sizeof(save)) {
3261
0
        memcpy(data, save, Py_MIN(nbytes, original_nbytes));
3262
0
    }
3263
0
    else {
3264
0
        size_t i = original_nbytes - ERASED_SIZE;
3265
0
        memcpy(data, save, Py_MIN(nbytes, (size_t)ERASED_SIZE));
3266
0
        if (nbytes > i) {
3267
0
            memcpy(data + i, &save[ERASED_SIZE],
3268
0
                   Py_MIN(nbytes - i, (size_t)ERASED_SIZE));
3269
0
        }
3270
0
    }
3271
0
#endif
3272
3273
0
    if (r == NULL) {
3274
0
        return NULL;
3275
0
    }
3276
3277
0
    if (nbytes > original_nbytes) {
3278
        /* growing: mark new extra memory clean */
3279
0
        memset(data + original_nbytes, PYMEM_CLEANBYTE,
3280
0
               nbytes - original_nbytes);
3281
0
    }
3282
3283
0
    return data;
3284
0
}
3285
3286
static inline void
3287
_PyMem_DebugCheckGIL(const char *func)
3288
0
{
3289
0
    PyThreadState *tstate = _PyThreadState_GET();
3290
0
    if (tstate == NULL) {
3291
0
#ifndef Py_GIL_DISABLED
3292
0
        _Py_FatalErrorFunc(func,
3293
0
                           "Python memory allocator called "
3294
0
                           "without holding the GIL");
3295
#else
3296
        _Py_FatalErrorFunc(func,
3297
                           "Python memory allocator called "
3298
                           "without an active thread state. "
3299
                           "Are you trying to call it inside of a Py_BEGIN_ALLOW_THREADS block?");
3300
#endif
3301
0
    }
3302
0
}
3303
3304
void *
3305
_PyMem_DebugMalloc(void *ctx, size_t nbytes)
3306
0
{
3307
0
    _PyMem_DebugCheckGIL(__func__);
3308
0
    return _PyMem_DebugRawMalloc(ctx, nbytes);
3309
0
}
3310
3311
void *
3312
_PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize)
3313
0
{
3314
0
    _PyMem_DebugCheckGIL(__func__);
3315
0
    return _PyMem_DebugRawCalloc(ctx, nelem, elsize);
3316
0
}
3317
3318
3319
void
3320
_PyMem_DebugFree(void *ctx, void *ptr)
3321
0
{
3322
0
    _PyMem_DebugCheckGIL(__func__);
3323
0
    _PyMem_DebugRawFree(ctx, ptr);
3324
0
}
3325
3326
3327
void *
3328
_PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes)
3329
0
{
3330
0
    _PyMem_DebugCheckGIL(__func__);
3331
0
    return _PyMem_DebugRawRealloc(ctx, ptr, nbytes);
3332
0
}
3333
3334
/* Check the forbidden bytes on both ends of the memory allocated for p.
3335
 * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress,
3336
 * and call Py_FatalError to kill the program.
3337
 * The API id, is also checked.
3338
 */
3339
static void
3340
_PyMem_DebugCheckAddress(const char *func, char api, const void *p)
3341
0
{
3342
0
    assert(p != NULL);
3343
3344
0
    const uint8_t *q = (const uint8_t *)p;
3345
0
    size_t nbytes;
3346
0
    const uint8_t *tail;
3347
0
    int i;
3348
0
    char id;
3349
3350
    /* Check the API id */
3351
0
    id = (char)q[-SST];
3352
0
    if (id != api) {
3353
0
        _PyObject_DebugDumpAddress(p);
3354
0
        _Py_FatalErrorFormat(func,
3355
0
                             "bad ID: Allocated using API '%c', "
3356
0
                             "verified using API '%c'",
3357
0
                             id, api);
3358
0
    }
3359
3360
    /* Check the stuff at the start of p first:  if there's underwrite
3361
     * corruption, the number-of-bytes field may be nuts, and checking
3362
     * the tail could lead to a segfault then.
3363
     */
3364
0
    for (i = SST-1; i >= 1; --i) {
3365
0
        if (*(q-i) != PYMEM_FORBIDDENBYTE) {
3366
0
            _PyObject_DebugDumpAddress(p);
3367
0
            _Py_FatalErrorFunc(func, "bad leading pad byte");
3368
0
        }
3369
0
    }
3370
3371
0
    nbytes = read_size_t(q - 2*SST);
3372
0
    tail = q + nbytes;
3373
0
    for (i = 0; i < SST; ++i) {
3374
0
        if (tail[i] != PYMEM_FORBIDDENBYTE) {
3375
0
            _PyObject_DebugDumpAddress(p);
3376
0
            _Py_FatalErrorFunc(func, "bad trailing pad byte");
3377
0
        }
3378
0
    }
3379
0
}
3380
3381
/* Display info to stderr about the memory block at p. */
3382
static void
3383
_PyObject_DebugDumpAddress(const void *p)
3384
0
{
3385
0
    const uint8_t *q = (const uint8_t *)p;
3386
0
    const uint8_t *tail;
3387
0
    size_t nbytes;
3388
0
    int i;
3389
0
    int ok;
3390
0
    char id;
3391
3392
0
    fprintf(stderr, "Debug memory block at address p=%p:", p);
3393
0
    if (p == NULL) {
3394
0
        fprintf(stderr, "\n");
3395
0
        return;
3396
0
    }
3397
0
    id = (char)q[-SST];
3398
0
    fprintf(stderr, " API '%c'\n", id);
3399
3400
0
    nbytes = read_size_t(q - 2*SST);
3401
0
    fprintf(stderr, "    %zu bytes originally requested\n", nbytes);
3402
3403
    /* In case this is nuts, check the leading pad bytes first. */
3404
0
    fprintf(stderr, "    The %d pad bytes at p-%d are ", SST-1, SST-1);
3405
0
    ok = 1;
3406
0
    for (i = 1; i <= SST-1; ++i) {
3407
0
        if (*(q-i) != PYMEM_FORBIDDENBYTE) {
3408
0
            ok = 0;
3409
0
            break;
3410
0
        }
3411
0
    }
3412
0
    if (ok)
3413
0
        fputs("FORBIDDENBYTE, as expected.\n", stderr);
3414
0
    else {
3415
0
        fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
3416
0
            PYMEM_FORBIDDENBYTE);
3417
0
        for (i = SST-1; i >= 1; --i) {
3418
0
            const uint8_t byte = *(q-i);
3419
0
            fprintf(stderr, "        at p-%d: 0x%02x", i, byte);
3420
0
            if (byte != PYMEM_FORBIDDENBYTE)
3421
0
                fputs(" *** OUCH", stderr);
3422
0
            fputc('\n', stderr);
3423
0
        }
3424
3425
0
        fputs("    Because memory is corrupted at the start, the "
3426
0
              "count of bytes requested\n"
3427
0
              "       may be bogus, and checking the trailing pad "
3428
0
              "bytes may segfault.\n", stderr);
3429
0
    }
3430
3431
0
    tail = q + nbytes;
3432
0
    fprintf(stderr, "    The %d pad bytes at tail=%p are ", SST, (void *)tail);
3433
0
    ok = 1;
3434
0
    for (i = 0; i < SST; ++i) {
3435
0
        if (tail[i] != PYMEM_FORBIDDENBYTE) {
3436
0
            ok = 0;
3437
0
            break;
3438
0
        }
3439
0
    }
3440
0
    if (ok)
3441
0
        fputs("FORBIDDENBYTE, as expected.\n", stderr);
3442
0
    else {
3443
0
        fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
3444
0
                PYMEM_FORBIDDENBYTE);
3445
0
        for (i = 0; i < SST; ++i) {
3446
0
            const uint8_t byte = tail[i];
3447
0
            fprintf(stderr, "        at tail+%d: 0x%02x",
3448
0
                    i, byte);
3449
0
            if (byte != PYMEM_FORBIDDENBYTE)
3450
0
                fputs(" *** OUCH", stderr);
3451
0
            fputc('\n', stderr);
3452
0
        }
3453
0
    }
3454
3455
#ifdef PYMEM_DEBUG_SERIALNO
3456
    size_t serial = read_size_t(tail + SST);
3457
    fprintf(stderr,
3458
            "    The block was made by call #%zu to debug malloc/realloc.\n",
3459
            serial);
3460
#endif
3461
3462
0
    if (nbytes > 0) {
3463
0
        i = 0;
3464
0
        fputs("    Data at p:", stderr);
3465
        /* print up to 8 bytes at the start */
3466
0
        while (q < tail && i < 8) {
3467
0
            fprintf(stderr, " %02x", *q);
3468
0
            ++i;
3469
0
            ++q;
3470
0
        }
3471
        /* and up to 8 at the end */
3472
0
        if (q < tail) {
3473
0
            if (tail - q > 8) {
3474
0
                fputs(" ...", stderr);
3475
0
                q = tail - 8;
3476
0
            }
3477
0
            while (q < tail) {
3478
0
                fprintf(stderr, " %02x", *q);
3479
0
                ++q;
3480
0
            }
3481
0
        }
3482
0
        fputc('\n', stderr);
3483
0
    }
3484
0
    fputc('\n', stderr);
3485
3486
0
    fflush(stderr);
3487
0
    _PyMem_DumpTraceback(fileno(stderr), p);
3488
0
}
3489
3490
3491
static size_t
3492
printone(FILE *out, const char* msg, size_t value)
3493
0
{
3494
0
    int i, k;
3495
0
    char buf[100];
3496
0
    size_t origvalue = value;
3497
3498
0
    fputs(msg, out);
3499
0
    for (i = (int)strlen(msg); i < 35; ++i)
3500
0
        fputc(' ', out);
3501
0
    fputc('=', out);
3502
3503
    /* Write the value with commas. */
3504
0
    i = 22;
3505
0
    buf[i--] = '\0';
3506
0
    buf[i--] = '\n';
3507
0
    k = 3;
3508
0
    do {
3509
0
        size_t nextvalue = value / 10;
3510
0
        unsigned int digit = (unsigned int)(value - nextvalue * 10);
3511
0
        value = nextvalue;
3512
0
        buf[i--] = (char)(digit + '0');
3513
0
        --k;
3514
0
        if (k == 0 && value && i >= 0) {
3515
0
            k = 3;
3516
0
            buf[i--] = ',';
3517
0
        }
3518
0
    } while (value && i >= 0);
3519
3520
0
    while (i >= 0)
3521
0
        buf[i--] = ' ';
3522
0
    fputs(buf, out);
3523
3524
0
    return origvalue;
3525
0
}
3526
3527
void
3528
_PyDebugAllocatorStats(FILE *out,
3529
                       const char *block_name, int num_blocks, size_t sizeof_block)
3530
0
{
3531
0
    char buf1[128];
3532
0
    char buf2[128];
3533
0
    PyOS_snprintf(buf1, sizeof(buf1),
3534
0
                  "%d %ss * %zd bytes each",
3535
0
                  num_blocks, block_name, sizeof_block);
3536
0
    PyOS_snprintf(buf2, sizeof(buf2),
3537
0
                  "%48s ", buf1);
3538
0
    (void)printone(out, buf2, num_blocks * sizeof_block);
3539
0
}
3540
3541
// Return true if the obmalloc state structure is heap allocated,
3542
// by PyMem_RawCalloc().  For the main interpreter, this structure
3543
// allocated in the BSS.  Allocating that way gives some memory savings
3544
// and a small performance win (at least on a demand paged OS).  On
3545
// 64-bit platforms, the obmalloc structure is 256 kB. Most of that
3546
// memory is for the arena_map_top array.  Since normally only one entry
3547
// of that array is used, only one page of resident memory is actually
3548
// used, rather than the full 256 kB.
3549
bool _PyMem_obmalloc_state_on_heap(PyInterpreterState *interp)
3550
0
{
3551
0
#if WITH_PYMALLOC
3552
0
    return interp->obmalloc && interp->obmalloc != &obmalloc_state_main;
3553
#else
3554
    return false;
3555
#endif
3556
0
}
3557
3558
#ifdef WITH_PYMALLOC
3559
static void
3560
init_obmalloc_pools(PyInterpreterState *interp)
3561
37
{
3562
    // initialize the obmalloc->pools structure.  This must be done
3563
    // before the obmalloc alloc/free functions can be called.
3564
37
    poolp temp[OBMALLOC_USED_POOLS_SIZE] =
3565
37
        _obmalloc_pools_INIT(interp->obmalloc->pools);
3566
37
    memcpy(&interp->obmalloc->pools.used, temp, sizeof(temp));
3567
37
}
3568
#endif /* WITH_PYMALLOC */
3569
3570
int _PyMem_init_obmalloc(PyInterpreterState *interp)
3571
37
{
3572
37
#ifdef WITH_PYMALLOC
3573
    /* Initialize obmalloc, but only for subinterpreters,
3574
       since the main interpreter is initialized statically. */
3575
37
    if (_Py_IsMainInterpreter(interp)
3576
0
            || _PyInterpreterState_HasFeature(interp,
3577
37
                                              Py_RTFLAGS_USE_MAIN_OBMALLOC)) {
3578
37
        interp->obmalloc = &obmalloc_state_main;
3579
37
        if (!obmalloc_state_initialized) {
3580
37
            init_obmalloc_pools(interp);
3581
37
            obmalloc_state_initialized = true;
3582
37
        }
3583
37
    } else {
3584
0
        interp->obmalloc = PyMem_RawCalloc(1, sizeof(struct _obmalloc_state));
3585
0
        if (interp->obmalloc == NULL) {
3586
0
            return -1;
3587
0
        }
3588
0
        init_obmalloc_pools(interp);
3589
0
    }
3590
37
#endif /* WITH_PYMALLOC */
3591
37
    return 0; // success
3592
37
}
3593
3594
3595
#ifdef WITH_PYMALLOC
3596
3597
static void
3598
free_obmalloc_arenas(PyInterpreterState *interp)
3599
0
{
3600
0
    OMState *state = interp->obmalloc;
3601
0
    for (uint i = 0; i < maxarenas; ++i) {
3602
        // free each obmalloc memory arena
3603
0
        struct arena_object *ao = &allarenas[i];
3604
0
        _PyObject_Arena.free(_PyObject_Arena.ctx,
3605
0
                             (void *)ao->address, ARENA_SIZE);
3606
0
    }
3607
    // free the array containing pointers to all arenas
3608
0
    PyMem_RawFree(allarenas);
3609
0
#if WITH_PYMALLOC_RADIX_TREE
3610
0
#ifdef USE_INTERIOR_NODES
3611
    // Free the middle and bottom nodes of the radix tree.  These are allocated
3612
    // by arena_map_mark_used() but not freed when arenas are freed.
3613
0
    for (int i1 = 0; i1 < MAP_TOP_LENGTH; i1++) {
3614
0
         arena_map_mid_t *mid = arena_map_root.ptrs[i1];
3615
0
         if (mid == NULL) {
3616
0
             continue;
3617
0
         }
3618
0
         for (int i2 = 0; i2 < MAP_MID_LENGTH; i2++) {
3619
0
            arena_map_bot_t *bot = arena_map_root.ptrs[i1]->ptrs[i2];
3620
0
            if (bot == NULL) {
3621
0
                continue;
3622
0
            }
3623
0
            PyMem_RawFree(bot);
3624
0
         }
3625
0
         PyMem_RawFree(mid);
3626
0
    }
3627
0
#endif
3628
0
#endif
3629
0
}
3630
3631
#ifdef Py_DEBUG
3632
/* Is target in the list?  The list is traversed via the nextpool pointers.
3633
 * The list may be NULL-terminated, or circular.  Return 1 if target is in
3634
 * list, else 0.
3635
 */
3636
static int
3637
pool_is_in_list(const poolp target, poolp list)
3638
{
3639
    poolp origlist = list;
3640
    assert(target != NULL);
3641
    if (list == NULL)
3642
        return 0;
3643
    do {
3644
        if (target == list)
3645
            return 1;
3646
        list = list->nextpool;
3647
    } while (list != NULL && list != origlist);
3648
    return 0;
3649
}
3650
#endif
3651
3652
#ifdef WITH_MIMALLOC
3653
struct _alloc_stats {
3654
    size_t allocated_blocks;
3655
    size_t allocated_bytes;
3656
    size_t allocated_with_overhead;
3657
    size_t bytes_reserved;
3658
    size_t bytes_committed;
3659
};
3660
3661
static bool _collect_alloc_stats(
3662
    const mi_heap_t* heap, const mi_heap_area_t* area,
3663
    void* block, size_t block_size, void* arg)
3664
0
{
3665
0
    struct _alloc_stats *stats = (struct _alloc_stats *)arg;
3666
0
    stats->allocated_blocks += area->used;
3667
0
    stats->allocated_bytes += area->used * area->block_size;
3668
0
    stats->allocated_with_overhead += area->used * area->full_block_size;
3669
0
    stats->bytes_reserved += area->reserved;
3670
0
    stats->bytes_committed += area->committed;
3671
0
    return 1;
3672
0
}
3673
3674
static void
3675
py_mimalloc_print_stats(FILE *out)
3676
0
{
3677
0
    fprintf(out, "Small block threshold = %zu, in %u size classes.\n",
3678
0
        (size_t)MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE);
3679
0
    fprintf(out, "Medium block threshold = %zu\n",
3680
0
            (size_t)MI_MEDIUM_OBJ_SIZE_MAX);
3681
0
    fprintf(out, "Large object max size = %zu\n",
3682
0
            (size_t)MI_LARGE_OBJ_SIZE_MAX);
3683
3684
0
    mi_heap_t *heap = mi_heap_get_default();
3685
0
    struct _alloc_stats stats;
3686
0
    memset(&stats, 0, sizeof(stats));
3687
0
    mi_heap_visit_blocks(heap, false, &_collect_alloc_stats, &stats);
3688
3689
0
    fprintf(out, "    Allocated Blocks: %zd\n", stats.allocated_blocks);
3690
0
    fprintf(out, "    Allocated Bytes: %zd\n", stats.allocated_bytes);
3691
0
    fprintf(out, "    Allocated Bytes w/ Overhead: %zd\n", stats.allocated_with_overhead);
3692
0
    fprintf(out, "    Bytes Reserved: %zd\n", stats.bytes_reserved);
3693
0
    fprintf(out, "    Bytes Committed: %zd\n", stats.bytes_committed);
3694
0
}
3695
#endif
3696
3697
3698
static void
3699
pymalloc_print_stats(FILE *out)
3700
0
{
3701
0
    OMState *state = get_state();
3702
3703
0
    uint i;
3704
0
    const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
3705
    /* # of pools, allocated blocks, and free blocks per class index */
3706
0
    size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
3707
0
    size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
3708
0
    size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
3709
    /* total # of allocated bytes in used and full pools */
3710
0
    size_t allocated_bytes = 0;
3711
    /* total # of available bytes in used pools */
3712
0
    size_t available_bytes = 0;
3713
    /* # of free pools + pools not yet carved out of current arena */
3714
0
    uint numfreepools = 0;
3715
    /* # of bytes for arena alignment padding */
3716
0
    size_t arena_alignment = 0;
3717
    /* # of bytes in used and full pools used for pool_headers */
3718
0
    size_t pool_header_bytes = 0;
3719
    /* # of bytes in used and full pools wasted due to quantization,
3720
     * i.e. the necessarily leftover space at the ends of used and
3721
     * full pools.
3722
     */
3723
0
    size_t quantization = 0;
3724
    /* # of arenas actually allocated. */
3725
0
    size_t narenas = 0;
3726
    /* running total -- should equal narenas * ARENA_SIZE */
3727
0
    size_t total;
3728
0
    char buf[128];
3729
3730
0
    fprintf(out, "Small block threshold = %d, in %u size classes.\n",
3731
0
            SMALL_REQUEST_THRESHOLD, numclasses);
3732
3733
0
    for (i = 0; i < numclasses; ++i)
3734
0
        numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
3735
3736
    /* Because full pools aren't linked to from anything, it's easiest
3737
     * to march over all the arenas.  If we're lucky, most of the memory
3738
     * will be living in full pools -- would be a shame to miss them.
3739
     */
3740
0
    for (i = 0; i < maxarenas; ++i) {
3741
0
        uintptr_t base = allarenas[i].address;
3742
3743
        /* Skip arenas which are not allocated. */
3744
0
        if (allarenas[i].address == (uintptr_t)NULL)
3745
0
            continue;
3746
0
        narenas += 1;
3747
3748
0
        numfreepools += allarenas[i].nfreepools;
3749
3750
        /* round up to pool alignment */
3751
0
        if (base & (uintptr_t)POOL_SIZE_MASK) {
3752
0
            arena_alignment += POOL_SIZE;
3753
0
            base &= ~(uintptr_t)POOL_SIZE_MASK;
3754
0
            base += POOL_SIZE;
3755
0
        }
3756
3757
        /* visit every pool in the arena */
3758
0
        assert(base <= (uintptr_t) allarenas[i].pool_address);
3759
0
        for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) {
3760
0
            poolp p = (poolp)base;
3761
0
            const uint sz = p->szidx;
3762
0
            uint freeblocks;
3763
3764
0
            if (p->ref.count == 0) {
3765
                /* currently unused */
3766
#ifdef Py_DEBUG
3767
                assert(pool_is_in_list(p, allarenas[i].freepools));
3768
#endif
3769
0
                continue;
3770
0
            }
3771
0
            ++numpools[sz];
3772
0
            numblocks[sz] += p->ref.count;
3773
0
            freeblocks = NUMBLOCKS(sz) - p->ref.count;
3774
0
            numfreeblocks[sz] += freeblocks;
3775
#ifdef Py_DEBUG
3776
            if (freeblocks > 0)
3777
                assert(pool_is_in_list(p, usedpools[sz + sz]));
3778
#endif
3779
0
        }
3780
0
    }
3781
0
    assert(narenas == narenas_currently_allocated);
3782
3783
0
    fputc('\n', out);
3784
0
    fputs("class   size   num pools   blocks in use  avail blocks\n"
3785
0
          "-----   ----   ---------   -------------  ------------\n",
3786
0
          out);
3787
3788
0
    for (i = 0; i < numclasses; ++i) {
3789
0
        size_t p = numpools[i];
3790
0
        size_t b = numblocks[i];
3791
0
        size_t f = numfreeblocks[i];
3792
0
        uint size = INDEX2SIZE(i);
3793
0
        if (p == 0) {
3794
0
            assert(b == 0 && f == 0);
3795
0
            continue;
3796
0
        }
3797
0
        fprintf(out, "%5u %6u %11zu %15zu %13zu\n",
3798
0
                i, size, p, b, f);
3799
0
        allocated_bytes += b * size;
3800
0
        available_bytes += f * size;
3801
0
        pool_header_bytes += p * POOL_OVERHEAD;
3802
0
        quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
3803
0
    }
3804
0
    fputc('\n', out);
3805
#ifdef PYMEM_DEBUG_SERIALNO
3806
    if (_PyMem_DebugEnabled()) {
3807
        (void)printone(out, "# times object malloc called", serialno);
3808
    }
3809
#endif
3810
0
    (void)printone(out, "# arenas allocated total", ntimes_arena_allocated);
3811
0
    (void)printone(out, "# arenas reclaimed", ntimes_arena_allocated - narenas);
3812
0
    (void)printone(out, "# arenas highwater mark", narenas_highwater);
3813
0
    (void)printone(out, "# arenas allocated current", narenas);
3814
3815
0
    PyOS_snprintf(buf, sizeof(buf),
3816
0
                  "%zu arenas * %d bytes/arena",
3817
0
                  narenas, ARENA_SIZE);
3818
0
    (void)printone(out, buf, narenas * ARENA_SIZE);
3819
3820
0
    fputc('\n', out);
3821
3822
    /* Account for what all of those arena bytes are being used for. */
3823
0
    total = printone(out, "# bytes in allocated blocks", allocated_bytes);
3824
0
    total += printone(out, "# bytes in available blocks", available_bytes);
3825
3826
0
    PyOS_snprintf(buf, sizeof(buf),
3827
0
        "%u unused pools * %d bytes", numfreepools, POOL_SIZE);
3828
0
    total += printone(out, buf, (size_t)numfreepools * POOL_SIZE);
3829
3830
0
    total += printone(out, "# bytes lost to pool headers", pool_header_bytes);
3831
0
    total += printone(out, "# bytes lost to quantization", quantization);
3832
0
    total += printone(out, "# bytes lost to arena alignment", arena_alignment);
3833
0
    (void)printone(out, "Total", total);
3834
0
    assert(narenas * ARENA_SIZE == total);
3835
3836
0
#if WITH_PYMALLOC_RADIX_TREE
3837
0
    fputs("\narena map counts\n", out);
3838
0
#ifdef USE_INTERIOR_NODES
3839
0
    (void)printone(out, "# arena map mid nodes", arena_map_mid_count);
3840
0
    (void)printone(out, "# arena map bot nodes", arena_map_bot_count);
3841
0
    fputc('\n', out);
3842
0
#endif
3843
0
    total = printone(out, "# bytes lost to arena map root", sizeof(arena_map_root));
3844
0
#ifdef USE_INTERIOR_NODES
3845
0
    total += printone(out, "# bytes lost to arena map mid",
3846
0
                      sizeof(arena_map_mid_t) * arena_map_mid_count);
3847
0
    total += printone(out, "# bytes lost to arena map bot",
3848
0
                      sizeof(arena_map_bot_t) * arena_map_bot_count);
3849
0
    (void)printone(out, "Total", total);
3850
0
#endif
3851
0
#endif
3852
3853
0
}
3854
3855
/* Print summary info to "out" about the state of pymalloc's structures.
3856
 * In Py_DEBUG mode, also perform some expensive internal consistency
3857
 * checks.
3858
 *
3859
 * Return 0 if the memory debug hooks are not installed or no statistics was
3860
 * written into out, return 1 otherwise.
3861
 */
3862
int
3863
_PyObject_DebugMallocStats(FILE *out)
3864
0
{
3865
0
#ifdef WITH_MIMALLOC
3866
0
    if (_PyMem_MimallocEnabled()) {
3867
0
        py_mimalloc_print_stats(out);
3868
0
        return 1;
3869
0
    }
3870
0
    else
3871
0
#endif
3872
0
    if (_PyMem_PymallocEnabled()) {
3873
0
        pymalloc_print_stats(out);
3874
0
        return 1;
3875
0
    }
3876
0
    else {
3877
0
        return 0;
3878
0
    }
3879
0
}
3880
3881
#endif /* #ifdef WITH_PYMALLOC */