mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-09 12:58:41 +03:00
Merge branch 'master' into feature/add-cleanup-mem-function
This commit is contained in:
commit
b5cc16b983
32 changed files with 900 additions and 1060 deletions
|
@ -22,8 +22,11 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).
|
||||
// #define MI_STAT 1
|
||||
|
||||
// Define MI_SECURE as 1 to encode free lists
|
||||
// #define MI_SECURE 1
|
||||
// Define MI_SECURE to enable security mitigations
|
||||
// #define MI_SECURE 1 // guard page around metadata
|
||||
// #define MI_SECURE 2 // guard page around each mimalloc page
|
||||
// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)
|
||||
// #define MI_SECURE 4 // checks for double free. (may be more expensive)
|
||||
|
||||
#if !defined(MI_SECURE)
|
||||
#define MI_SECURE 0
|
||||
|
@ -33,17 +36,23 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
#define MI_USER_CLEANUP 0
|
||||
#endif
|
||||
|
||||
// Define MI_DEBUG as 1 for basic assert checks and statistics
|
||||
// set it to 2 to do internal asserts,
|
||||
// and to 3 to do extensive invariant checking.
|
||||
// Define MI_DEBUG for debug mode
|
||||
// #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free.
|
||||
// #define MI_DEBUG 2 // + internal assertion checks
|
||||
// #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON)
|
||||
#if !defined(MI_DEBUG)
|
||||
#if !defined(NDEBUG) || defined(_DEBUG)
|
||||
#define MI_DEBUG 1
|
||||
#define MI_DEBUG 2
|
||||
#else
|
||||
#define MI_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Encoded free lists allow detection of corrupted free lists
|
||||
// and can detect buffer overflows and double `free`s.
|
||||
#if (MI_SECURE>=3 || MI_DEBUG>=1)
|
||||
#define MI_ENCODE_FREELIST 1
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Platform specific values
|
||||
|
@ -118,6 +127,8 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
#error "define more bins"
|
||||
#endif
|
||||
|
||||
// The free lists use encoded next fields
|
||||
// (Only actually encodes when MI_ENCODED_FREELIST is defined.)
|
||||
typedef uintptr_t mi_encoded_t;
|
||||
|
||||
// free lists contain blocks
|
||||
|
@ -126,6 +137,7 @@ typedef struct mi_block_s {
|
|||
} mi_block_t;
|
||||
|
||||
|
||||
// The delayed flags are used for efficient multi-threaded free-ing
|
||||
typedef enum mi_delayed_e {
|
||||
MI_NO_DELAYED_FREE = 0,
|
||||
MI_USE_DELAYED_FREE = 1,
|
||||
|
@ -135,15 +147,13 @@ typedef enum mi_delayed_e {
|
|||
|
||||
|
||||
// The `in_full` and `has_aligned` page flags are put in a union to efficiently
|
||||
// test if both are false (`value == 0`) in the `mi_free` routine.
|
||||
typedef union mi_page_flags_u {
|
||||
uint16_t value;
|
||||
uint8_t full_aligned;
|
||||
// test if both are false (`full_aligned == 0`) in the `mi_free` routine.
|
||||
typedef union mi_page_flags_s {
|
||||
uint8_t full_aligned;
|
||||
struct {
|
||||
bool in_full:1;
|
||||
bool has_aligned:1;
|
||||
bool is_zero; // `true` if the blocks in the free list are zero initialized
|
||||
};
|
||||
uint8_t in_full : 1;
|
||||
uint8_t has_aligned : 1;
|
||||
} x;
|
||||
} mi_page_flags_t;
|
||||
|
||||
// Thread free list.
|
||||
|
@ -171,18 +181,19 @@ typedef uintptr_t mi_thread_free_t;
|
|||
typedef struct mi_page_s {
|
||||
// "owned" by the segment
|
||||
uint8_t segment_idx; // index in the segment `pages` array, `page == &segment->pages[page->segment_idx]`
|
||||
bool segment_in_use:1; // `true` if the segment allocated this page
|
||||
bool is_reset:1; // `true` if the page memory was reset
|
||||
bool is_committed:1; // `true` if the page virtual memory is committed
|
||||
bool is_zero_init:1; // `true` if the page was zero initialized
|
||||
uint8_t segment_in_use:1; // `true` if the segment allocated this page
|
||||
uint8_t is_reset:1; // `true` if the page memory was reset
|
||||
uint8_t is_committed:1; // `true` if the page virtual memory is committed
|
||||
uint8_t is_zero_init:1; // `true` if the page was zero initialized
|
||||
|
||||
// layout like this to optimize access in `mi_malloc` and `mi_free`
|
||||
uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear`
|
||||
uint16_t reserved; // number of blocks reserved in memory
|
||||
mi_page_flags_t flags; // `in_full` and `has_aligned` flags (16 bits)
|
||||
mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits)
|
||||
bool is_zero; // `true` if the blocks in the free list are zero initialized
|
||||
|
||||
mi_block_t* free; // list of available free blocks (`malloc` allocates from this list)
|
||||
#if MI_SECURE
|
||||
#ifdef MI_ENCODE_FREELIST
|
||||
uintptr_t cookie; // random cookie to encode the free lists
|
||||
#endif
|
||||
size_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`)
|
||||
|
@ -199,8 +210,8 @@ typedef struct mi_page_s {
|
|||
|
||||
// improve page index calculation
|
||||
// without padding: 10 words on 64-bit, 11 on 32-bit. Secure adds one word
|
||||
#if (MI_INTPTR_SIZE==8 && MI_SECURE>0) || (MI_INTPTR_SIZE==4 && MI_SECURE==0)
|
||||
void* padding[1]; // 12 words on 64-bit in secure mode, 12 words on 32-bit plain
|
||||
#if (MI_INTPTR_SIZE==8 && defined(MI_ENCODE_FREELIST)) || (MI_INTPTR_SIZE==4 && !defined(MI_ENCODE_FREELIST))
|
||||
void* padding[1]; // 12 words on 64-bit with cookie, 12 words on 32-bit plain
|
||||
#endif
|
||||
} mi_page_t;
|
||||
|
||||
|
@ -342,14 +353,14 @@ typedef struct mi_stats_s {
|
|||
mi_stat_count_t page_committed;
|
||||
mi_stat_count_t segments_abandoned;
|
||||
mi_stat_count_t pages_abandoned;
|
||||
mi_stat_count_t pages_extended;
|
||||
mi_stat_count_t mmap_calls;
|
||||
mi_stat_count_t commit_calls;
|
||||
mi_stat_count_t threads;
|
||||
mi_stat_count_t huge;
|
||||
mi_stat_count_t giant;
|
||||
mi_stat_count_t malloc;
|
||||
mi_stat_count_t segments_cache;
|
||||
mi_stat_counter_t pages_extended;
|
||||
mi_stat_counter_t mmap_calls;
|
||||
mi_stat_counter_t commit_calls;
|
||||
mi_stat_counter_t page_no_retire;
|
||||
mi_stat_counter_t searches;
|
||||
mi_stat_counter_t huge_count;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue