Skip to content

Commit 45c37c5

Browse files
committed
Update vendored mimalloc to caaf3bc41494e6b58ab32ed9c851b3c8b61a8f82
Vendor mimalloc v3 (dev3 branch) into Objects/mimalloc and Include/internal/mimalloc.
1 parent f0a7b43 commit 45c37c5

99 files changed

Lines changed: 21664 additions & 12072 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* ----------------------------------------------------------------------------
2+
Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
3+
This is free software; you can redistribute it and/or modify it under the
4+
terms of the MIT license. A copy of the license can be found in the file
5+
"LICENSE" at the root of this distribution.
6+
-----------------------------------------------------------------------------*/
7+
#pragma once
8+
#ifndef MIMALLOC_NEW_DELETE_H
9+
#define MIMALLOC_NEW_DELETE_H
10+
11+
// ----------------------------------------------------------------------------
12+
// This header provides convenient overrides for the new and
13+
// delete operations in C++.
14+
//
15+
// This header should be included in only one source file!
16+
//
17+
// On Windows, or when linking dynamically with mimalloc, these
18+
// can be more performant than the standard new-delete operations.
19+
// See <https://en.cppreference.com/w/cpp/memory/new/operator_new>
20+
// ---------------------------------------------------------------------------
21+
#if defined(__cplusplus)
22+
#include <new>
23+
#include "mimalloc.h"
24+
25+
#if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)
26+
// stay consistent with VCRT definitions
27+
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)
28+
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)
29+
#else
30+
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict
31+
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict
32+
#endif
33+
34+
void operator delete(void* p) noexcept { mi_free(p); };
35+
void operator delete[](void* p) noexcept { mi_free(p); };
36+
37+
void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
38+
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
39+
40+
mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
41+
mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }
42+
43+
mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
44+
mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
45+
46+
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
47+
void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); };
48+
void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); };
49+
#endif
50+
51+
#if (__cplusplus > 201402L && defined(__cpp_aligned_new))
52+
void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
53+
void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
54+
void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
55+
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
56+
void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
57+
void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
58+
59+
void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
60+
void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
61+
void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
62+
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
63+
#endif
64+
#endif
65+
66+
#endif // MIMALLOC_NEW_DELETE_H
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* ----------------------------------------------------------------------------
2+
Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
3+
This is free software; you can redistribute it and/or modify it under the
4+
terms of the MIT license. A copy of the license can be found in the file
5+
"LICENSE" at the root of this distribution.
6+
-----------------------------------------------------------------------------*/
7+
#pragma once
8+
#ifndef MIMALLOC_OVERRIDE_H
9+
#define MIMALLOC_OVERRIDE_H
10+
11+
/* ----------------------------------------------------------------------------
12+
This header can be used to statically redirect malloc/free and new/delete
13+
to the mimalloc variants. This can be useful if one can include this file on
14+
each source file in a project (but be careful when using external code to
15+
not accidentally mix pointers from different allocators).
16+
-----------------------------------------------------------------------------*/
17+
18+
#include "mimalloc.h"
19+
20+
// Standard C allocation
21+
#define malloc(n) mi_malloc(n)
22+
#define calloc(c,n) mi_calloc(c,n)
23+
#define realloc(p,n) mi_realloc(p,n)
24+
#define free(p) mi_free(p)
25+
26+
#define strdup(s) mi_strdup(s)
27+
#define strndup(s,n) mi_strndup(s,n)
28+
#define realpath(f,n) mi_realpath(f,n)
29+
30+
// Microsoft extensions
31+
#define _expand(p,n) mi_expand(p,n)
32+
#define _msize(p) mi_usable_size(p)
33+
#define _recalloc(p,c,n) mi_recalloc(p,c,n)
34+
35+
#define _strdup(s) mi_strdup(s)
36+
#define _strndup(s,n) mi_strndup(s,n)
37+
#define _wcsdup(s) mi_wcsdup(s)
38+
#define _mbsdup(s) mi_mbsdup(s)
39+
#define _dupenv_s(buf,n,nm) mi_dupenv_s(buf,n,nm)
40+
#define _wdupenv_s(buf,n,nm) mi_wdupenv_s(buf,n,nm)
41+
42+
// Various Posix and Unix variants
43+
#define reallocf(p,n) mi_reallocf(p,n)
44+
#define malloc_size(p) mi_usable_size(p)
45+
#define malloc_usable_size(p) mi_usable_size(p)
46+
#define malloc_good_size(n) mi_malloc_good_size(n)
47+
#define cfree(p) mi_free(p)
48+
49+
#define valloc(n) mi_valloc(n)
50+
#define pvalloc(n) mi_pvalloc(n)
51+
#define reallocarray(p,c,n) mi_reallocarray(p,c,n)
52+
#define reallocarr(ptrp,c,n) mi_reallocarr(ptrp,c,n)
53+
#define memalign(a,n) mi_memalign(a,n)
54+
#define aligned_alloc(a,n) mi_aligned_alloc(a,n)
55+
#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n)
56+
#define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n)
57+
58+
// Microsoft aligned variants
59+
#define _aligned_malloc(n,a) mi_malloc_aligned(n,a)
60+
#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a)
61+
#define _aligned_recalloc(p,c,n,a) mi_aligned_recalloc(p,c,n,a)
62+
#define _aligned_msize(p,a,o) mi_usable_size(p)
63+
#define _aligned_free(p) mi_free(p)
64+
#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o)
65+
#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o)
66+
#define _aligned_offset_recalloc(p,c,n,a,o) mi_recalloc_aligned_at(p,c,n,a,o)
67+
68+
#endif // MIMALLOC_OVERRIDE_H
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* ----------------------------------------------------------------------------
2+
Copyright (c) 2024-2026, Microsoft Research, Daan Leijen
3+
This is free software; you can redistribute it and/or modify it under the
4+
terms of the MIT license. A copy of the license can be found in the file
5+
"LICENSE" at the root of this distribution.
6+
-----------------------------------------------------------------------------*/
7+
#pragma once
8+
#ifndef MIMALLOC_PROFILE_H
9+
#define MIMALLOC_PROFILE_H
10+
11+
#include "mimalloc.h"
12+
#include <stdbool.h> // bool
13+
#include <stdint.h> // uint64_t
14+
15+
//---------------------------------------------------------------------------
16+
// Initial support for profiling hooks; still experimental
17+
//---------------------------------------------------------------------------
18+
19+
#define MI_PROFILE_SAMPLE_DATA_MAX_SIZE (1024)
20+
21+
// User defined profiler; see `test_profile.c` for an example.
22+
typedef struct mi_profiler_s mi_profiler_t;
23+
24+
// Profiler data is stored together with each sampled allocation (unless the `on_free` field in the profiler is NULL.)
25+
typedef struct mi_profiler_sample_data_s {
26+
size_t user_data_size; // size of the user_data (should be the `mi_profiler_t.sample_data_size`)
27+
void* user_data[1]; // default, but can be less or more (up to 1KiB), depending on `sample_data_size`
28+
} mi_profiler_sample_data_t;
29+
30+
// Profiling callback invoked on each sampled allocation.
31+
// If `profiler_data!=NULL` (i.e. when `on_free` is not NULL), then `profiler_data->requested_size == requested_size`.
32+
typedef size_t (mi_cdecl mi_profiler_on_alloc_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, size_t requested_size, size_t bytes_sample_rate, uint64_t bytes_since_last_sample, mi_heap_t* heap);
33+
34+
// Profiling callback invoked on each sampled in-place re-allocation.
35+
typedef size_t (mi_cdecl mi_profiler_on_realloc_inplace_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, size_t old_size, mi_heap_t* heap);
36+
37+
// Profiling callback invoked on a previously sampled allocation.
38+
typedef void (mi_cdecl mi_profiler_on_free_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, mi_heap_t* heap);
39+
40+
// Profiling callback invoked on mi_profiler_snapshot()
41+
typedef void (mi_cdecl mi_profiler_on_snapshot_fun)(mi_profiler_t* profiler);
42+
43+
// A profiler
44+
// All fields are considered immutable such that they can be copied and accessed concurrently. All fields can be NULL/0.
45+
struct mi_profiler_s {
46+
void* reserved; // opaque; reserved by mimalloc
47+
size_t sample_data_size; // size of required profiler data for each sampled allocation (or zero for no data)
48+
size_t initial_sample_rate;// initial sample rate in bytes (set to at least 1 or higher) (can be adjusted by `on_alloc`)
49+
mi_profiler_on_alloc_fun* on_alloc; // called on a sampled allocation (may be called concurrently)
50+
mi_profiler_on_free_fun* on_free; // called on when previous sampled allocation is freed (may be called concurrently)
51+
mi_profiler_on_realloc_inplace_fun* on_realloc_inplace; // (as yet unused) called on in-place reallocation of a previous sampled allocation (may be called concurrently)
52+
mi_profiler_on_snapshot_fun* on_snapshot; // called on mi_profiler_snapshot() (only one thread at a time)
53+
// ... more user fields allowed
54+
};
55+
56+
// Exported definitions
57+
#ifdef __cplusplus
58+
extern "C" {
59+
#endif
60+
61+
// attach a profiler to a particular heap only.
62+
mi_decl_export bool mi_heap_profile(mi_heap_t* heap, mi_profiler_t* profiler);
63+
64+
// disable profiling for a particular heap; useful for a heap that the profiler uses itself for metadata.
65+
mi_decl_export void mi_heap_profile_disable(mi_heap_t* heap);
66+
67+
// attach a profiler to any (current and future) heaps in a sub-process (unless those heaps disabled profiling)
68+
mi_decl_export bool mi_subproc_profile(mi_subproc_id_t subproc_id, mi_profiler_t* profiler);
69+
70+
// attach a profiler to any heaps in the main sub-process (use NULL to detach)
71+
mi_decl_export bool mi_profile(mi_profiler_t* profiler);
72+
73+
// start sampling
74+
mi_decl_export bool mi_profiler_start(mi_profiler_t* profiler);
75+
76+
// end sampling
77+
mi_decl_export bool mi_profiler_stop(mi_profiler_t* profiler);
78+
79+
// snapshot the current profile (may be called concurrently but only one thread will actually call the snapshot callback)
80+
mi_decl_export void mi_profiler_snapshot(mi_profiler_t* profiler);
81+
82+
// builtin pprof compatible profiler
83+
// the builtin profiler can also be activated using environment variables (see [`pprof.c`](/src/profile/pprof.c))
84+
// `base_file_name` selects the text snapshot format if it ends in `.heap` or `.text` (the extension is
85+
// stripped); any other extension, or none, uses the default (protobuf) snapshot format.
86+
// `alloc_interval_size`, if >0, automatically snapshots every that many allocated bytes.
87+
// `inuse_interval_size`, if >0, automatically snapshots every time the in-use bytes grow by that many bytes.
88+
// `time_interval_secs`, if >0, automatically snapshots every that many seconds (checked from allocation events).
89+
mi_decl_export mi_profiler_t* mi_pprof_profiler_new(size_t initial_threshold, const char* base_file_name, size_t alloc_interval_size, size_t inuse_interval_size, size_t time_interval_secs);
90+
mi_decl_export void mi_pprof_profiler_delete(mi_profiler_t* profiler);
91+
92+
93+
#ifdef __cplusplus
94+
}
95+
#endif
96+
97+
#endif // MIMALLOC_PROFILE_H

0 commit comments

Comments
 (0)